diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 608c4e7..c61e91e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,17 +12,17 @@ jobs: - uses: actions/checkout@v3 - uses: denoland/setup-deno@v1 with: - deno-version: v1.36 + deno-version: v1.37 - name: Setup Fluent CI CLI run: deno install -A -r https://cli.fluentci.io -n fluentci - name: Setup Dagger run: | - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh - sudo mv bin/dagger /usr/local/bin - dagger version + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.8 sh + sudo mv bin/dagger /usr/local/bin + dagger version - name: Run Dagger Pipelines - run: dagger run fluentci deno_pipeline fmt lint test + run: fluentci run deno_pipeline fmt lint test - name: Upload coverage to Codecov - run: dagger run fluentci codecov_pipeline + run: fluentci run codecov_pipeline env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/example.yml b/.github/workflows/example.yml index c768abe..d95b6d5 100644 --- a/.github/workflows/example.yml +++ b/.github/workflows/example.yml @@ -17,7 +17,7 @@ jobs: run: deno install -A -r https://cli.fluentci.io -n fluentci - name: Setup Dagger run: | - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.8 sh sudo mv bin/dagger /usr/local/bin dagger version - name: Run Dagger Pipelines @@ -26,4 +26,4 @@ jobs: dagger run deno run -A ../src/dagger/runner.ts image working-directory: example env: - TRIVY_IMAGE: snyk/snyk:alpine + TRIVY_IMAGE: hashicorp/terraform:latest diff --git a/.github/workflows/zenith.yml b/.github/workflows/zenith.yml new file mode 100644 index 0000000..3c81d58 --- /dev/null +++ b/.github/workflows/zenith.yml @@ -0,0 +1,23 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Zenith Example +on: + push: + branches: + - zenith + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Dagger Zenith + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.8 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: | + dagger query --doc config.gql + dagger query --doc image.gql + working-directory: example diff --git a/README.md b/README.md index 04ec458..eeab8a7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Trivy Pipeline [![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) -![deno compatibility](https://shield.deno.dev/deno/^1.34) +![deno compatibility](https://shield.deno.dev/deno/^1.37) [![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) A ready-to-use CI/CD Pipeline for scanning vulnerabilities using [Trivy](https://trivy.dev/). @@ -46,19 +46,35 @@ fluentci run . | image | Scan a container image | | sbom | Scan a software bill of materials | +```graphql +config(exitCode: Int!, src: String!): String + +fs(exitCode: Int!, src: String!): String + +image( + exitCode: Int!, + image: String!, + src: String! +): String + +repo( + exitCode: Int!, + repoUrl: String!, + src: String! +): String + +sbom( + exitCode: Int!, + path: String!, + src: String! +): String +``` ## Programmatic usage You can also use this pipeline programmatically: ```ts -import Client, { connect } from "https://sdk.fluentci.io/v0.1.9/mod.ts"; -import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.1.0/mod.ts"; - -function pipeline(src = ".") { - connect(async (client: Client) => { - await fs(client, src); - }); -} +import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.2.0/mod.ts"; -pipeline(); +await fs(); ``` diff --git a/ci.ts b/ci.ts index b4b4de4..8b71220 100644 --- a/ci.ts +++ b/ci.ts @@ -1,10 +1,3 @@ -import Client, { connect } from "https://sdk.fluentci.io/v0.1.9/mod.ts"; -import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.1.0/mod.ts"; +import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.2.0/mod.ts"; -function pipeline(src = ".") { - connect(async (client: Client) => { - await fs(client, src); - }); -} - -pipeline(); +await fs(); diff --git a/dagger.json b/dagger.json new file mode 100644 index 0000000..675fa77 --- /dev/null +++ b/dagger.json @@ -0,0 +1,5 @@ +{ + "root": "", + "name": "trivy", + "sdkRuntime": "tsiry/dagger-sdk-deno" +} \ No newline at end of file diff --git a/deno.json b/deno.json index d976349..e0e77b5 100644 --- a/deno.json +++ b/deno.json @@ -3,15 +3,29 @@ "tasks": { "esm:add": "deno run -A https://esm.sh/v128 add", "esm:update": "deno run -A https://esm.sh/v128 update", - "esm:remove": "deno run -A https://esm.sh/v128 remove" + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "schema": "deno run -A src/dagger/schema.ts", + "clean": "rm -rf gen schema.graphql" }, "fmt": { - "exclude": ["example/", ".fluentci/"] + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] }, "lint": { - "exclude": ["example/", ".fluentci/"] + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] }, "test": { - "exclude": ["example/", ".fluentci/"] + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] } -} +} \ No newline at end of file diff --git a/deno.lock b/deno.lock index bb2d8e7..2d79a93 100644 --- a/deno.lock +++ b/deno.lock @@ -2,12 +2,33 @@ "version": "3", "packages": { "specifiers": { - "npm:@types/node": "npm:@types/node@18.16.19" + "npm:@types/node": "npm:@types/node@18.16.19", + "npm:nexus": "npm:nexus@1.3.0_graphql@16.8.1" }, "npm": { "@types/node@18.16.19": { "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", "dependencies": {} + }, + "graphql@16.8.1": { + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "dependencies": {} + }, + "iterall@1.3.0": { + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "dependencies": {} + }, + "nexus@1.3.0_graphql@16.8.1": { + "integrity": "sha512-w/s19OiNOs0LrtP7pBmD9/FqJHvZLmCipVRt6v1PM8cRUYIbhEswyNKGHVoC4eHZGPSnD+bOf5A3+gnbt0A5/A==", + "dependencies": { + "graphql": "graphql@16.8.1", + "iterall": "iterall@1.3.0", + "tslib": "tslib@2.6.2" + } + }, + "tslib@2.6.2": { + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dependencies": {} } } }, @@ -95,6 +116,44 @@ "https://deno.land/std@0.191.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", "https://deno.land/std@0.191.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", "https://deno.land/std@0.191.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/std@0.203.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", + "https://deno.land/std@0.203.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.203.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343", + "https://deno.land/std@0.203.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.203.0/path/_dirname.ts": "355e297236b2218600aee7a5301b937204c62e12da9db4b0b044993d9e658395", + "https://deno.land/std@0.203.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664", + "https://deno.land/std@0.203.0/path/_format.ts": "4a99270d6810f082e614309164fad75d6f1a483b68eed97c830a506cc589f8b4", + "https://deno.land/std@0.203.0/path/_from_file_url.ts": "6eadfae2e6f63ad9ee46b26db4a1b16583055c0392acedfb50ed2fc694b6f581", + "https://deno.land/std@0.203.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.203.0/path/_is_absolute.ts": "05dac10b5e93c63198b92e3687baa2be178df5321c527dc555266c0f4f51558c", + "https://deno.land/std@0.203.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e", + "https://deno.land/std@0.203.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81", + "https://deno.land/std@0.203.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2", + "https://deno.land/std@0.203.0/path/_parse.ts": "0f9b0ff43682dd9964eb1c4398610c4e165d8db9d3ac9d594220217adf480cfa", + "https://deno.land/std@0.203.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5", + "https://deno.land/std@0.203.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6", + "https://deno.land/std@0.203.0/path/_to_file_url.ts": "a141e4a525303e1a3a0c0571fd024552b5f3553a2af7d75d1ff3a503dcbb66d8", + "https://deno.land/std@0.203.0/path/_to_namespaced_path.ts": "0d5f4caa2ed98ef7a8786286df6af804b50e38859ae897b5b5b4c8c5930a75c8", + "https://deno.land/std@0.203.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221", + "https://deno.land/std@0.203.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930", + "https://deno.land/std@0.203.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.203.0/path/dirname.ts": "b6533f4ee4174a526dec50c279534df5345836dfdc15318400b08c62a62a39dd", + "https://deno.land/std@0.203.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf", + "https://deno.land/std@0.203.0/path/format.ts": "110270b238514dd68455a4c54956215a1aff7e37e22e4427b7771cefe1920aa5", + "https://deno.land/std@0.203.0/path/from_file_url.ts": "9f5cb58d58be14c775ec2e57fc70029ac8b17ed3bd7fe93e475b07280adde0ac", + "https://deno.land/std@0.203.0/path/glob.ts": "593e2c3573883225c25c5a21aaa8e9382a696b8e175ea20a3b6a1471ad17aaed", + "https://deno.land/std@0.203.0/path/is_absolute.ts": "0b92eb35a0a8780e9f16f16bb23655b67dace6a8e0d92d42039e518ee38103c1", + "https://deno.land/std@0.203.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8", + "https://deno.land/std@0.203.0/path/mod.ts": "6e1efb0b13121463aedb53ea51dabf5639a3172ab58c89900bbb72b486872532", + "https://deno.land/std@0.203.0/path/normalize.ts": "6ea523e0040979dd7ae2f1be5bf2083941881a252554c0f32566a18b03021955", + "https://deno.land/std@0.203.0/path/parse.ts": "be8de342bb9e1924d78dc4d93c45215c152db7bf738ec32475560424b119b394", + "https://deno.land/std@0.203.0/path/posix.ts": "0a1c1952d132323a88736d03e92bd236f3ed5f9f079e5823fae07c8d978ee61b", + "https://deno.land/std@0.203.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61", + "https://deno.land/std@0.203.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc", + "https://deno.land/std@0.203.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f", + "https://deno.land/std@0.203.0/path/to_file_url.ts": "00e6322373dd51ad109956b775e4e72e5f9fa68ce2c6b04e4af2a6eed3825d31", + "https://deno.land/std@0.203.0/path/to_namespaced_path.ts": "1b1db3055c343ab389901adfbda34e82b7386bcd1c744d54f9c1496ee0fd0c3d", + "https://deno.land/std@0.203.0/path/win32.ts": "8b3f80ef7a462511d5e8020ff490edcaa0a0d118f1b1e9da50e2916bdd73f9dd", "https://deno.land/std@0.52.0/fmt/colors.ts": "ec9d653672a9a3c7b6eafe53c5bc797364a2db2dcf766ab649c1155fea7a80b2", "https://deno.land/x/crc32@v0.2.0/mod.ts": "de7a3fa2d4ef24b96fc21e1cc4d2d65d1d2b1dcea92f63960e3e11bfa82df0fa", "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts": "79cc758901d20a3573d7e3cc2db9f0a5fe56833f4d9befcedc072b94d542eec7", @@ -138,6 +197,7 @@ "https://deno.land/x/zod@v3.22.1/mod.ts": "64e55237cb4410e17d968cd08975566059f27638ebb0b86048031b987ba251c4", "https://deno.land/x/zod@v3.22.1/types.ts": "4edc1823385f446532c8c9f676d84550c6dc54b17135e34508576647d9612d0e", "https://esm.sh/@dagger.io/dagger@0.8.4": "424bddc1457c1fc4975c978425730be068b5414e92dca7a64f2d80e2123c4719", + "https://esm.sh/graphql-tag@2.12.6": "2d8f017bc251d9e7346bafc3f3aef4b65f7fdc302c6e0d085e3359f44c893068", "https://esm.sh/nanoid@4.0.2": "df5af492771eb7ed903cec5e5d8ff721bc75e6c09ddf9fc9263215c8497961f4", "https://esm.sh/stringify-tree@1.1.1": "a0515b0f4fe97a6972047a588b7982592d9079e7aeac3323b0d26448a757cf84", "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", @@ -191,11 +251,19 @@ "https://esm.sh/yaml@v2.3.1": "5471fa3592a8a9d1a4a3d8cacf54070b01aedaca82f14fdbbdd056a491db00ec", "https://nix.fluentci.io/v0.5.1/deps.ts": "d2fee07fcb79b609f64f988990ad5d67c7bf17455f75dcbf1b3bbfa5de7c73b2", "https://nix.fluentci.io/v0.5.1/src/dagger/steps.ts": "b766f4fa9624a032e7af884a5ca47bc666a529c4a472d38b74b55ca0d63cf81d", + "https://nix.fluentci.io/zenith/deps.ts": "a8fd3aa32faea5de2779cc6494471b4fd9588f039d199ff1a1ff1b00343aef26", + "https://nix.fluentci.io/zenith/src/dagger/steps.ts": "b766f4fa9624a032e7af884a5ca47bc666a529c4a472d38b74b55ca0d63cf81d", "https://sdk.fluentci.io/v0.1.9/deps.ts": "1b036b7614a602b11e062a6911f26a6e2ac4e470cc74ac230125afd466cc77ea", "https://sdk.fluentci.io/v0.1.9/mod.ts": "a3c03bdb97c5a3b998c7c9f616c7b00d4268013c3b16e8a90c1a36a85529d841", "https://sdk.fluentci.io/v0.1.9/src/client.ts": "a8dd54861feccd11a53df39b2d45bfb3b2a8a3dff509f5700c41b517d4dff44d", "https://sdk.fluentci.io/v0.1.9/src/connect.ts": "1bb42b4e0c5073bb2125b90f1d7d08a66fcad9ad8c453924b944be72d3a56c98", "https://sdk.fluentci.io/v0.1.9/src/context.ts": "2939ff58d0a79d7377d5553e725c9a2110a0013035a5a57abe9a9a5da975c4ce", - "https://sdk.fluentci.io/v0.1.9/src/utils.ts": "394d131cfd465f0f3d8f876237f3bad1ab4dba73b9b7a396ee705d02aee40c16" + "https://sdk.fluentci.io/v0.1.9/src/utils.ts": "394d131cfd465f0f3d8f876237f3bad1ab4dba73b9b7a396ee705d02aee40c16", + "https://sdk.fluentci.io/z1/deps.ts": "1b036b7614a602b11e062a6911f26a6e2ac4e470cc74ac230125afd466cc77ea", + "https://sdk.fluentci.io/z1/mod.ts": "261ba81a4728f5def4e327a5cd80664ea8449515a2f4eea5f3f416acae39a1fa", + "https://sdk.fluentci.io/z1/src/client.ts": "dde6d20c41df43e5bb7763782eb3702a8d830a827444d1fb388fc574b2e6a64c", + "https://sdk.fluentci.io/z1/src/connect.ts": "4aff111c403cf78672384a10214a9885e08319dde579ec458f98a7bb04874101", + "https://sdk.fluentci.io/z1/src/context.ts": "2939ff58d0a79d7377d5553e725c9a2110a0013035a5a57abe9a9a5da975c4ce", + "https://sdk.fluentci.io/z1/src/utils.ts": "5dcd6d83553930502069d067ff42bc44698e22c23426fdb78630c4b39769d308" } } diff --git a/deps.ts b/deps.ts index 63ef493..06b55cb 100644 --- a/deps.ts +++ b/deps.ts @@ -1,11 +1,31 @@ export { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; -import Client from "https://sdk.fluentci.io/v0.1.9/mod.ts"; +import Client from "https://sdk.fluentci.io/z1/mod.ts"; export default Client; -export { connect, uploadContext } from "https://sdk.fluentci.io/v0.1.9/mod.ts"; +export { + connect, + uploadContext, + CacheSharingMode, +} from "https://sdk.fluentci.io/z1/mod.ts"; export { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; -export { withDevbox } from "https://nix.fluentci.io/v0.5.1/src/dagger/steps.ts"; +export { withDevbox } from "https://nix.fluentci.io/zenith/src/dagger/steps.ts"; export { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; +import gql from "https://esm.sh/graphql-tag@2.12.6"; +export { gql }; + +export { + arg, + queryType, + stringArg, + intArg, + nonNull, + makeSchema, +} from "npm:nexus"; +export { + dirname, + join, + resolve, +} from "https://deno.land/std@0.203.0/path/mod.ts"; export * as FluentGitlabCI from "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts"; export * as FluentGithubActions from "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts"; diff --git a/example/.fluentci/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..9c1cbb5 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Codecov + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.34 + - name: Create coverage files + run: deno test --allow-read --coverage=coverage --lock-write # create coverage files + - name: Create coverage report + run: deno coverage ./coverage --lcov > coverage.lcov # create coverage report + - name: Collect coverage + uses: codecov/codecov-action@v3 # upload the report on Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: ./coverage.lcov diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/.fluentci/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/LICENSE b/example/.fluentci/.fluentci/.fluentci/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/README.md b/example/.fluentci/.fluentci/.fluentci/.fluentci/README.md new file mode 100644 index 0000000..23f6a94 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/README.md @@ -0,0 +1,88 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use GitLab CI Pipeline and Jobs for your Deno projects. + +## ๐Ÿš€ Usage + +Quick start: + +```ts +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { pipeline } = GitLab; + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +Or, if you want to use the predefined jobs: + +```ts +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci/mod.ts"; +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = GitLab; + +const const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +It will generate the following `.gitlab-ci.yml` file: + +```yaml +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test +``` + +## ๐Ÿงช Advanced Usage + +This package also provides a ready-to-use pipeline for +[Dagger](https://dagger.io/), just run the following command on your Deno +project: + +```sh +dagger run deno run -A https://deno.land/x/deno_pipeline/ci.ts +``` + +Or, if you want to use the predefined jobs: + +```ts +import Client, { connect } from "@dagger.io/dagger"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/ci.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.json b/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.lock b/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.lock new file mode 100644 index 0000000..a364136 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/deno.lock @@ -0,0 +1,68 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/codecov_pipeline@v0.1.0/src/dagger/jobs.ts": "e980479e0bcd759773286145f3345ce7e1662c7d6734bfc4bbf8e6bfc93b974e", + "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts": "a34aea3753c7079de5877f592ce31f30d05d552155729ff3e695d77326405133", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.lock b/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.nix b/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/import_map.json b/example/.fluentci/.fluentci/.fluentci/.fluentci/import_map.json new file mode 100644 index 0000000..12c59ff --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/import_map.json @@ -0,0 +1,28 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "fluent_github_actions": "https://deno.land/x/fluent_github_actions@v0.1.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/mod.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..658ed39 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,197 @@ +import Client from "@dagger.io/dagger"; +import { upload } from "https://deno.land/x/codecov_pipeline@v0.1.0/src/dagger/jobs.ts"; +import { withDevbox } from "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", + deploy = "deploy", + codecov = "codecov", +} + +const baseCtr = (client: Client, pipeline: string) => { + if (existsSync("devbox.json")) { + return withDevbox( + client + .pipeline(pipeline) + .container() + .from("alpine:latest") + .withExec(["apk", "update"]) + .withExec(["apk", "add", "bash", "curl"]) + .withMountedCache("/nix", client.cacheVolume("nix")) + .withMountedCache("/etc/nix", client.cacheVolume("nix-etc")) + ); + } + return client.pipeline(pipeline).container().from("denoland/deno:alpine"); +}; + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.lint) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.fmt) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--coverage=coverage", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.test) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command) + .withExec(["sh", "-c", "deno coverage ./coverage --lcov > coverage.lcov"]); + + await ctr.file("/app/coverage.lcov").export("./coverage.lcov"); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const deploy = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let installDeployCtl = [ + "deno", + "install", + "--allow-all", + "--no-check", + "-r", + "-f", + "https://deno.land/x/deploy/deployctl.ts", + ]; + const project = Deno.env.get("DENO_PROJECT"); + const noStatic = Deno.env.get("NO_STATIC"); + const exclude = Deno.env.get("EXCLUDE"); + + let command = ["deployctl", "deploy"]; + + if (noStatic) { + command = command.concat(["--no-static"]); + } + + if (exclude) { + command = command.concat([`--exclude=${exclude}`]); + } + + if (!Deno.env.get("DENO_DEPLOY_TOKEN")) { + throw new Error("DENO_DEPLOY_TOKEN environment variable is not set"); + } + + if (!project) { + throw new Error("DENO_PROJECT environment variable is not set"); + } + + const script = Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx"; + command = command.concat([`--project=${project}`, script]); + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + installDeployCtl = [ + "sh", + "-c", + `devbox run -- ${installDeployCtl.join(" ")}`, + ]; + } + + const ctr = baseCtr(client, Job.deploy) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withEnvVariable("PATH", "/root/.deno/bin:$PATH", { expand: true }) + .withEnvVariable("DENO_DEPLOY_TOKEN", Deno.env.get("DENO_DEPLOY_TOKEN")!) + .withEnvVariable( + "DENO_MAIN_SCRIPT", + Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx" + ) + .withExec(installDeployCtl) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const codecov = upload; + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, + [Job.deploy]: deploy, + [Job.codecov]: upload, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", + [Job.deploy]: "Deploy your code to Deno Deploy", + [Job.codecov]: "Upload your code coverage to Codecov", +}; diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/config.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/config.ts new file mode 100644 index 0000000..2a25ea1 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/config.ts @@ -0,0 +1,52 @@ +import { JobSpec, Workflow } from "fluent_github_actions"; + +export function generateYaml() { + const workflow = new Workflow("Codecov"); + + const push = { + branches: ["main"], + }; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version`; + + const tests: JobSpec = { + "runs-on": "ubuntu-latest", + steps: [ + { + uses: "actions/checkout@v3", + }, + { + uses: "denoland/setup-deno@v1", + with: { + "deno-version": "v1.36", + }, + }, + { + name: "Setup Fluent CI CLI", + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + name: "Setup Dagger", + run: setupDagger, + }, + { + name: "List Jobs", + run: "fluentci ls .", + }, + { + name: "Run Dagger Pipelines", + run: "dagger run fluentci . fmt lint test codecov", + env: { + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}", + }, + }, + ], + }; + + workflow.on({ push }).jobs({ tests }); + + workflow.save(".github/workflows/ci.yml"); +} diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/init.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/init.ts new file mode 100644 index 0000000..6097dd5 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/github/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml(); diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..326531d --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +# Do not edit this file directly. It is generated by Fluent Github Actions + +name: Codecov +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: List Jobs + run: fluentci ls . + - name: Run Dagger Pipelines + run: dagger run fluentci . fmt lint test codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/example/.fluentci/.fluentci/.fluentci/.gitignore b/example/.fluentci/.fluentci/.fluentci/.gitignore new file mode 100644 index 0000000..a2442bb --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.gitignore @@ -0,0 +1,2 @@ +coverage/ +coverage.lcov \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/.fluentci/LICENSE b/example/.fluentci/.fluentci/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/README.md b/example/.fluentci/.fluentci/.fluentci/README.md new file mode 100644 index 0000000..b8517c1 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/README.md @@ -0,0 +1,69 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use CI/CD Pipeline for your Deno projects. + +## ๐Ÿš€ Usage + +Run the following command: + +```bash +dagger run fluentci deno_pipeline +``` + +Or, if you want to use it as a template: + +```bash +fluentci init -t deno +``` + +This will create a `.fluentci` folder in your project. + +Now you can run the pipeline with: + +```bash +dagger run fluentci . +``` + +## Environment variables (Deno Deploy) + +| Variable | Description | Default | +| ----------------- | ------------------------- | ---------- | +| DENO_PROJECT | Your project name | | +| NO_STATIC | Disable static assets | `false` | +| EXCLUDE | Exclude files from deploy | | +| DENO_DEPLOY_TOKEN | Your Deno Deploy token | | +| DENO_MAIN_SCRIPT | Your main script | `main.tsx` | + +## Jobs + +| Job | Description | Options | +| ------ | ------------------------------ | ---------------------- | +| fmt | Format your code | | +| lint | Lint your code | | +| test | Run your tests | `{ ignore: string[] }` | +| deploy | Deploy your app to Deno Deploy | | + +## Programmatic usage + +You can also use this pipeline programmatically: + +```ts +import { Client, connect } from "https://esm.sh/@dagger.io/dagger@0.8.1"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/.fluentci/ci.ts b/example/.fluentci/.fluentci/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/.fluentci/deno.json b/example/.fluentci/.fluentci/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/deno.lock b/example/.fluentci/.fluentci/.fluentci/deno.lock new file mode 100644 index 0000000..a874952 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/deno.lock @@ -0,0 +1,97 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/std@0.191.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.191.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.191.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/x/codecov_pipeline@v0.1.0/src/dagger/jobs.ts": "e980479e0bcd759773286145f3345ce7e1662c7d6734bfc4bbf8e6bfc93b974e", + "https://deno.land/x/codecov_pipeline@v0.1.1/src/dagger/jobs.ts": "ea5ea4fb985f879fdd1c0aed77ac635ba090606c1ecce9d5f5c107493d287984", + "https://deno.land/x/fluent_github_actions@v0.1.2/mod.ts": "dc62b622791da77bc27f68e33cba618983a0770a9a12dcc9e0f9a61161bb90e5", + "https://deno.land/x/fluent_github_actions@v0.1.2/src/event.ts": "c31430af085682cb4ad522c655a8a0800a3ab8b8aec7c979d60c909051d853b0", + "https://deno.land/x/fluent_github_actions@v0.1.2/src/job_spec.ts": "ee7af83e75285b4776ff4f9e14764187737178b4abc6c277da1c32491c41dfca", + "https://deno.land/x/fluent_github_actions@v0.1.2/src/step_spec.ts": "3207071b5dee8487f36fe4ea1881e8fd3b77c472c965c20a14093a3c919af9af", + "https://deno.land/x/fluent_github_actions@v0.1.2/src/workflow.ts": "488556e230fdeeb3a5b0d0bf548c570606aa356b0a7f667ea1d031d3263eb566", + "https://deno.land/x/fluent_github_actions@v0.1.2/src/workflow_spec.ts": "3ca9e565dc1dedd0531e0b852d50b9a3853a1ad35f2010760e0326590b80fa43", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts": "3becefe569f5c9814dffa1b534794a42b948481753a5903fa1b48d5337206ced", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/src/environment.ts": "f12ee4fb50e5100fccec29dc1d35aa430bfe8373e84286a8ab9f7b8e178f14e3", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/src/gitlabci.ts": "85d2335622c2def4a9554a9d8b8de4e62156f5d76d59a553e157bab4e6b6591f", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/src/gitlabci_spec.ts": "b60f40ecf26d243db2391aee70fdf71b133de3faaf789052020f58f98cf1b500", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/src/index.ts": "b5e374a24e3bca1d6fead0861f2c1b1e09e087a17e59297263f681ee71c972fe", + "https://deno.land/x/fluent_gitlab_ci@v0.3.2/src/job.ts": "a1ddf8d37ca33239de9d2c61f98835e585f6671748b37af8d647ebba5e1a9974", + "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts": "a34aea3753c7079de5877f592ce31f30d05d552155729ff3e695d77326405133", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe", + "https://esm.sh/v130/yaml@2.3.1/denonext/yaml.mjs": "71f677b4bfc69271af9d98db5194e354f9a1863955e208e26d32a9ef78bd89f5", + "https://esm.sh/yaml@v2.3.1": "9f8730b9d2fdb4d9320be0c0e62d57936097826342588991d561ae35555aca55" + }, + "npm": { + "specifiers": { + "@types/node": "@types/node@18.16.19" + }, + "packages": { + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + } + } + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..9c1cbb5 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Codecov + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.34 + - name: Create coverage files + run: deno test --allow-read --coverage=coverage --lock-write # create coverage files + - name: Create coverage report + run: deno coverage ./coverage --lcov > coverage.lcov # create coverage report + - name: Collect coverage + uses: codecov/codecov-action@v3 # upload the report on Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: ./coverage.lcov diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md new file mode 100644 index 0000000..23f6a94 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md @@ -0,0 +1,88 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use GitLab CI Pipeline and Jobs for your Deno projects. + +## ๐Ÿš€ Usage + +Quick start: + +```ts +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { pipeline } = GitLab; + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +Or, if you want to use the predefined jobs: + +```ts +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci/mod.ts"; +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = GitLab; + +const const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +It will generate the following `.gitlab-ci.yml` file: + +```yaml +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test +``` + +## ๐Ÿงช Advanced Usage + +This package also provides a ready-to-use pipeline for +[Dagger](https://dagger.io/), just run the following command on your Deno +project: + +```sh +dagger run deno run -A https://deno.land/x/deno_pipeline/ci.ts +``` + +Or, if you want to use the predefined jobs: + +```ts +import Client, { connect } from "@dagger.io/dagger"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock new file mode 100644 index 0000000..23cc878 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock @@ -0,0 +1,66 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json new file mode 100644 index 0000000..801ea9a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json @@ -0,0 +1,27 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..42b4554 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,111 @@ +import Client from "@dagger.io/dagger"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", +} + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.lint) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.fmt) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.test) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", +}; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..9c1cbb5 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Codecov + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.34 + - name: Create coverage files + run: deno test --allow-read --coverage=coverage --lock-write # create coverage files + - name: Create coverage report + run: deno coverage ./coverage --lcov > coverage.lcov # create coverage report + - name: Collect coverage + uses: codecov/codecov-action@v3 # upload the report on Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: ./coverage.lcov diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/LICENSE b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/README.md b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/README.md new file mode 100644 index 0000000..1afc7c6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/README.md @@ -0,0 +1,58 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use CI/CD Pipeline for your Deno projects. + +## ๐Ÿš€ Usage + +Run the following command: + +```bash +dagger run fluentci deno_pipeline +``` + +Or, if you want to use it as a template: + +```bash +fluentci init -t deno +``` + +This will create a `.fluentci` folder in your project. + +Now you can run the pipeline with: + +```bash +dagger run fluentci . +``` + +## Jobs + +| Job | Description | Options | +| ----- | ---------------- | ---------------------- | +| fmt | Format your code | | +| lint | Lint your code | | +| test | Run your tests | `{ ignore: string[] }` | + +## Programmatic usage + +You can also use this pipeline programmatically: + +```ts +import Client, { connect } from "@dagger.io/dagger"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/ci.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.lock b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.lock new file mode 100644 index 0000000..f8af4c3 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/deno.lock @@ -0,0 +1,67 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts": "a34aea3753c7079de5877f592ce31f30d05d552155729ff3e695d77326405133", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe" + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.lock b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.nix b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/import_map.json b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/import_map.json new file mode 100644 index 0000000..801ea9a --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/import_map.json @@ -0,0 +1,27 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/mod.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..611a5e0 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,188 @@ +import Client from "@dagger.io/dagger"; +import { withDevbox } from "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", + deploy = "deploy", +} + +const baseCtr = (client: Client, pipeline: string) => { + if (existsSync("devbox.json")) { + return withDevbox( + client + .pipeline(pipeline) + .container() + .from("alpine:latest") + .withExec(["apk", "update"]) + .withExec(["apk", "add", "bash", "curl"]) + .withMountedCache("/nix", client.cacheVolume("nix")) + .withMountedCache("/etc/nix", client.cacheVolume("nix-etc")) + ); + } + return client.pipeline(pipeline).container().from("denoland/deno:alpine"); +}; + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.lint) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.fmt) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.test) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const deploy = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let installDeployCtl = [ + "deno", + "install", + "--allow-all", + "--no-check", + "-r", + "-f", + "https://deno.land/x/deploy/deployctl.ts", + ]; + const project = Deno.env.get("DENO_PROJECT"); + const noStatic = Deno.env.get("NO_STATIC"); + const exclude = Deno.env.get("EXCLUDE"); + + let command = ["deployctl", "deploy"]; + + if (noStatic) { + command = command.concat(["--no-static"]); + } + + if (exclude) { + command = command.concat([`--exclude=${exclude}`]); + } + + if (!Deno.env.get("DENO_DEPLOY_TOKEN")) { + throw new Error("DENO_DEPLOY_TOKEN environment variable is not set"); + } + + if (!project) { + throw new Error("DENO_PROJECT environment variable is not set"); + } + + const script = Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx"; + command = command.concat([`--project=${project}`, script]); + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + installDeployCtl = [ + "sh", + "-c", + `devbox run -- ${installDeployCtl.join(" ")}`, + ]; + } + + const ctr = baseCtr(client, Job.deploy) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withEnvVariable("PATH", "/root/.deno/bin:$PATH", { expand: true }) + .withEnvVariable("DENO_DEPLOY_TOKEN", Deno.env.get("DENO_DEPLOY_TOKEN")!) + .withEnvVariable( + "DENO_MAIN_SCRIPT", + Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx" + ) + .withExec(installDeployCtl) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, + [Job.deploy]: deploy, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", + [Job.deploy]: "Deploy your code to Deno Deploy", +}; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/.fluentci/example/.vscode/settings.json b/example/.fluentci/.fluentci/.fluentci/example/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/.fluentci/example/README.md b/example/.fluentci/.fluentci/.fluentci/example/README.md new file mode 100644 index 0000000..a6193e1 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/README.md @@ -0,0 +1,16 @@ +# Deno Pipeline Example + +This is an example using the [Deno Pipeline](https://github.com/fluent-ci-templates/deno-pipeline). + +## ๐Ÿš€ Usage + +You need to set the following environment variables: + +- `DENO_DEPLOY_TOKEN`: Your Deno Deploy token. +- `DENO_PROJECT`: Your project name. + +Then, run the following command: + +```bash +dagger run fluentci . fmt lint deploy +``` \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/example/main.tsx b/example/.fluentci/.fluentci/.fluentci/example/main.tsx new file mode 100644 index 0000000..dd48266 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/example/main.tsx @@ -0,0 +1,20 @@ +/** @jsx h */ +import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; +import html, { h } from "https://deno.land/x/htm@0.2.1/mod.ts"; + +const handler = (req: Request) => + html({ + title: "Hello World!", + styles: [ + "html, body { margin: 0; height: 100%; }", + "body { background: #86efac; display: flex; flex-direction: column; align-items: center; justify-content: center; }", + ], + body: ( + + +

Hello Patricia!

+ + ), + }); + +serve(handler); diff --git a/example/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/.fluentci/flake.lock b/example/.fluentci/.fluentci/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/.fluentci/flake.nix b/example/.fluentci/.fluentci/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/import_map.json b/example/.fluentci/.fluentci/.fluentci/import_map.json new file mode 100644 index 0000000..12c59ff --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/import_map.json @@ -0,0 +1,28 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "fluent_github_actions": "https://deno.land/x/fluent_github_actions@v0.1.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.fluentci/mod.ts b/example/.fluentci/.fluentci/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..862b599 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,197 @@ +import Client from "@dagger.io/dagger"; +import { upload } from "https://deno.land/x/codecov_pipeline@v0.1.1/src/dagger/jobs.ts"; +import { withDevbox } from "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", + deploy = "deploy", + codecov = "codecov", +} + +const baseCtr = (client: Client, pipeline: string) => { + if (existsSync("devbox.json")) { + return withDevbox( + client + .pipeline(pipeline) + .container() + .from("alpine:latest") + .withExec(["apk", "update"]) + .withExec(["apk", "add", "bash", "curl"]) + .withMountedCache("/nix", client.cacheVolume("nix")) + .withMountedCache("/etc/nix", client.cacheVolume("nix-etc")) + ); + } + return client.pipeline(pipeline).container().from("denoland/deno:alpine"); +}; + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.lint) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.fmt) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--coverage=coverage", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.test) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command) + .withExec(["sh", "-c", "deno coverage ./coverage --lcov > coverage.lcov"]); + + const result = await ctr.stdout(); + + await ctr.file("/app/coverage.lcov").export("./coverage.lcov"); + + console.log(result); +}; + +export const deploy = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let installDeployCtl = [ + "deno", + "install", + "--allow-all", + "--no-check", + "-r", + "-f", + "https://deno.land/x/deploy/deployctl.ts", + ]; + const project = Deno.env.get("DENO_PROJECT"); + const noStatic = Deno.env.get("NO_STATIC"); + const exclude = Deno.env.get("EXCLUDE"); + + let command = ["deployctl", "deploy"]; + + if (noStatic) { + command = command.concat(["--no-static"]); + } + + if (exclude) { + command = command.concat([`--exclude=${exclude}`]); + } + + if (!Deno.env.get("DENO_DEPLOY_TOKEN")) { + throw new Error("DENO_DEPLOY_TOKEN environment variable is not set"); + } + + if (!project) { + throw new Error("DENO_PROJECT environment variable is not set"); + } + + const script = Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx"; + command = command.concat([`--project=${project}`, script]); + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + installDeployCtl = [ + "sh", + "-c", + `devbox run -- ${installDeployCtl.join(" ")}`, + ]; + } + + const ctr = baseCtr(client, Job.deploy) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withEnvVariable("PATH", "/root/.deno/bin:$PATH", { expand: true }) + .withEnvVariable("DENO_DEPLOY_TOKEN", Deno.env.get("DENO_DEPLOY_TOKEN")!) + .withEnvVariable( + "DENO_MAIN_SCRIPT", + Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx" + ) + .withExec(installDeployCtl) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const codecov = upload; + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, + [Job.deploy]: deploy, + [Job.codecov]: upload, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", + [Job.deploy]: "Deploy your code to Deno Deploy", + [Job.codecov]: "Upload your code coverage to Codecov", +}; diff --git a/example/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/.fluentci/src/github/config.ts b/example/.fluentci/.fluentci/.fluentci/src/github/config.ts new file mode 100644 index 0000000..420b6d6 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/github/config.ts @@ -0,0 +1,52 @@ +import { JobSpec, Workflow } from "fluent_github_actions"; + +export function generateYaml() { + const workflow = new Workflow("Codecov"); + + const push = { + branches: ["main"], + }; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version`; + + const tests: JobSpec = { + "runs-on": "ubuntu-latest", + steps: [ + { + uses: "actions/checkout@v3", + }, + { + uses: "denoland/setup-deno@v1", + with: { + "deno-version": "v1.36", + }, + }, + { + name: "Setup Fluent CI CLI", + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + name: "Setup Dagger", + run: setupDagger, + }, + { + name: "Run Dagger Pipelines", + run: "dagger run fluentci . fmt lint test", + }, + { + name: "Upload to Codecov", + run: "dagger run fluentci codecov_pipeline", + env: { + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}", + }, + }, + ], + }; + + workflow.on({ push }).jobs({ tests }); + + workflow.save(".github/workflows/ci.yml"); +} diff --git a/example/.fluentci/.fluentci/.fluentci/src/github/init.ts b/example/.fluentci/.fluentci/.fluentci/src/github/init.ts new file mode 100644 index 0000000..6097dd5 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/github/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml(); diff --git a/example/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..03db0af --- /dev/null +++ b/example/.fluentci/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +# Do not edit this file directly. It is generated by Fluent Github Actions + +name: Codecov +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: dagger run fluentci . fmt lint test + - name: Upload to Codecov + run: dagger run fluentci codecov_pipeline + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/example/.fluentci/.fluentci/.gitignore b/example/.fluentci/.fluentci/.gitignore new file mode 100644 index 0000000..a2442bb --- /dev/null +++ b/example/.fluentci/.fluentci/.gitignore @@ -0,0 +1,2 @@ +coverage/ +coverage.lcov \ No newline at end of file diff --git a/example/.fluentci/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/LICENSE b/example/.fluentci/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/README.md b/example/.fluentci/.fluentci/README.md new file mode 100644 index 0000000..b8517c1 --- /dev/null +++ b/example/.fluentci/.fluentci/README.md @@ -0,0 +1,69 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use CI/CD Pipeline for your Deno projects. + +## ๐Ÿš€ Usage + +Run the following command: + +```bash +dagger run fluentci deno_pipeline +``` + +Or, if you want to use it as a template: + +```bash +fluentci init -t deno +``` + +This will create a `.fluentci` folder in your project. + +Now you can run the pipeline with: + +```bash +dagger run fluentci . +``` + +## Environment variables (Deno Deploy) + +| Variable | Description | Default | +| ----------------- | ------------------------- | ---------- | +| DENO_PROJECT | Your project name | | +| NO_STATIC | Disable static assets | `false` | +| EXCLUDE | Exclude files from deploy | | +| DENO_DEPLOY_TOKEN | Your Deno Deploy token | | +| DENO_MAIN_SCRIPT | Your main script | `main.tsx` | + +## Jobs + +| Job | Description | Options | +| ------ | ------------------------------ | ---------------------- | +| fmt | Format your code | | +| lint | Lint your code | | +| test | Run your tests | `{ ignore: string[] }` | +| deploy | Deploy your app to Deno Deploy | | + +## Programmatic usage + +You can also use this pipeline programmatically: + +```ts +import { Client, connect } from "https://esm.sh/@dagger.io/dagger@0.8.1"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/ci.ts b/example/.fluentci/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/deno.json b/example/.fluentci/.fluentci/deno.json new file mode 100644 index 0000000..d976349 --- /dev/null +++ b/example/.fluentci/.fluentci/deno.json @@ -0,0 +1,17 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove" + }, + "fmt": { + "exclude": ["example/", ".fluentci/"] + }, + "lint": { + "exclude": ["example/", ".fluentci/"] + }, + "test": { + "exclude": ["example/", ".fluentci/"] + } +} diff --git a/example/.fluentci/.fluentci/deno.lock b/example/.fluentci/.fluentci/deno.lock new file mode 100644 index 0000000..2dbd29d --- /dev/null +++ b/example/.fluentci/.fluentci/deno.lock @@ -0,0 +1,89 @@ +{ + "version": "3", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/codecov_pipeline@v0.1.0/src/dagger/jobs.ts": "e980479e0bcd759773286145f3345ce7e1662c7d6734bfc4bbf8e6bfc93b974e", + "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts": "dc62b622791da77bc27f68e33cba618983a0770a9a12dcc9e0f9a61161bb90e5", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/event.ts": "d44d42356a04aea7ba64ff9e9a12090f477605c27a940bbf80aba612e4e96d1e", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/job_spec.ts": "93aa5b8b79cd8baaf875901322c4c38c27d4458439a831cb0ad86401b207a3dc", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/step_spec.ts": "b399949d1fd9c45873cdda70d82c92e3d9d96ba9a1d5749f3010a1f242b20e35", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/workflow.ts": "c9e3b7b3a59f7edff958eae8f27a8542f2a24889ea27c8aa016d0c0b0ca416c6", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/workflow_spec.ts": "b5c696dc70ee3f777a565197c6a3a379d87d026e12d59942fef5b9dc72124c3a", + "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts": "a34aea3753c7079de5877f592ce31f30d05d552155729ff3e695d77326405133", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://deno.land/x/zod@v3.22.1/ZodError.ts": "4de18ff525e75a0315f2c12066b77b5c2ae18c7c15ef7df7e165d63536fdf2ea", + "https://deno.land/x/zod@v3.22.1/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", + "https://deno.land/x/zod@v3.22.1/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", + "https://deno.land/x/zod@v3.22.1/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", + "https://deno.land/x/zod@v3.22.1/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", + "https://deno.land/x/zod@v3.22.1/helpers/parseUtil.ts": "f791e6e65a0340d85ad37d26cd7a3ba67126cd9957eac2b7163162155283abb1", + "https://deno.land/x/zod@v3.22.1/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", + "https://deno.land/x/zod@v3.22.1/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", + "https://deno.land/x/zod@v3.22.1/helpers/util.ts": "8baf19b19b2fca8424380367b90364b32503b6b71780269a6e3e67700bb02774", + "https://deno.land/x/zod@v3.22.1/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", + "https://deno.land/x/zod@v3.22.1/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", + "https://deno.land/x/zod@v3.22.1/mod.ts": "64e55237cb4410e17d968cd08975566059f27638ebb0b86048031b987ba251c4", + "https://deno.land/x/zod@v3.22.1/types.ts": "4edc1823385f446532c8c9f676d84550c6dc54b17135e34508576647d9612d0e", + "https://esm.sh/stringify-tree@1.1.1": "a0515b0f4fe97a6972047a588b7982592d9079e7aeac3323b0d26448a757cf84", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v132/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v132/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "eaa9333a5219638ad170d12e12603ae00ae80fc8bf02cc112cfec7294e6bcb43", + "https://esm.sh/v132/yaml@2.3.1/denonext/yaml.mjs": "71f677b4bfc69271af9d98db5194e354f9a1863955e208e26d32a9ef78bd89f5", + "https://esm.sh/yaml@v2.3.1": "5471fa3592a8a9d1a4a3d8cacf54070b01aedaca82f14fdbbdd056a491db00ec" + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json new file mode 100644 index 0000000..39a38ae --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Debian", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/nix:1": {} + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "nix develop --experimental-features \"nix-command flakes\"" + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..9c1cbb5 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Codecov + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.34 + - name: Create coverage files + run: deno test --allow-read --coverage=coverage --lock-write # create coverage files + - name: Create coverage report + run: deno coverage ./coverage --lcov > coverage.lcov # create coverage report + - name: Collect coverage + uses: codecov/codecov-action@v3 # upload the report on Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: ./coverage.lcov diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md new file mode 100644 index 0000000..23f6a94 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/README.md @@ -0,0 +1,88 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use GitLab CI Pipeline and Jobs for your Deno projects. + +## ๐Ÿš€ Usage + +Quick start: + +```ts +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { pipeline } = GitLab; + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +Or, if you want to use the predefined jobs: + +```ts +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci/mod.ts"; +import { GitLab } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = GitLab; + +const const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +pipeline.write(); // Write the pipeline to the file .gitlab-ci.yml +``` + +It will generate the following `.gitlab-ci.yml` file: + +```yaml +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test +``` + +## ๐Ÿงช Advanced Usage + +This package also provides a ready-to-use pipeline for +[Dagger](https://dagger.io/), just run the following command on your Deno +project: + +```sh +dagger run deno run -A https://deno.land/x/deno_pipeline/ci.ts +``` + +Or, if you want to use the predefined jobs: + +```ts +import Client, { connect } from "@dagger.io/dagger"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock new file mode 100644 index 0000000..23cc878 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/deno.lock @@ -0,0 +1,66 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe" + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json new file mode 100644 index 0000000..801ea9a --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/import_map.json @@ -0,0 +1,27 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..42b4554 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,111 @@ +import Client from "@dagger.io/dagger"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", +} + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.lint) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.fmt) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = client + .pipeline(Job.test) + .container() + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", +}; diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..9c1cbb5 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Codecov + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.34 + - name: Create coverage files + run: deno test --allow-read --coverage=coverage --lock-write # create coverage files + - name: Create coverage report + run: deno coverage ./coverage --lcov > coverage.lcov # create coverage report + - name: Collect coverage + uses: codecov/codecov-action@v3 # upload the report on Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + file: ./coverage.lcov diff --git a/example/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json b/example/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e9c20f9 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/deno-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/example/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md b/example/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e50de72 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug +report, new feature, correction, or additional documentation, we greatly value +feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests +to ensure we have all the necessary information to effectively respond to your +bug report or contribution. + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest +features. + +When filing an issue, please check existing open, or recently closed, issues to +make sure somebody else hasn't already reported the issue. Please try to include +as much information as you can. Details like these are incredibly useful: + +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment + +## Contributing via Pull Requests + +Contributions via pull requests are much appreciated. Before sending us a pull +request, please ensure that: + +1. You are working against the latest source on the _master_ branch. +2. You check existing open, and recently merged, pull requests to make sure + someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your + time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. + If you also reformat all the code, it will be hard for us to focus on your + change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request + interface. +6. Pay attention to any automated CI failures reported in the pull request, and + stay involved in the conversation. + +GitHub provides additional document on +[forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +Looking at the existing issues is a great way to find something to contribute +on. As our projects, by default, use the default GitHub issue labels +(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any +'help wanted' issues is a great place to start. + +## Code of Conduct + +This project has adopted the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to +confirm the licensing of your contribution. diff --git a/example/.fluentci/.fluentci/example/.fluentci/LICENSE b/example/.fluentci/.fluentci/example/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/.fluentci/example/.fluentci/README.md b/example/.fluentci/.fluentci/example/.fluentci/README.md new file mode 100644 index 0000000..1afc7c6 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/README.md @@ -0,0 +1,58 @@ +# Deno Pipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +A ready-to-use CI/CD Pipeline for your Deno projects. + +## ๐Ÿš€ Usage + +Run the following command: + +```bash +dagger run fluentci deno_pipeline +``` + +Or, if you want to use it as a template: + +```bash +fluentci init -t deno +``` + +This will create a `.fluentci` folder in your project. + +Now you can run the pipeline with: + +```bash +dagger run fluentci . +``` + +## Jobs + +| Job | Description | Options | +| ----- | ---------------- | ---------------------- | +| fmt | Format your code | | +| lint | Lint your code | | +| test | Run your tests | `{ ignore: string[] }` | + +## Programmatic usage + +You can also use this pipeline programmatically: + +```ts +import Client, { connect } from "@dagger.io/dagger"; +import { Dagger } from "https://deno.land/x/deno_pipeline/mod.ts"; + +const { fmt, lint, test } = Dagger; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +pipeline(); +``` diff --git a/example/.fluentci/.fluentci/example/.fluentci/ci.ts b/example/.fluentci/.fluentci/example/.fluentci/ci.ts new file mode 100644 index 0000000..67e5a80 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/ci.ts @@ -0,0 +1,12 @@ +const command = new Deno.Command(Deno.execPath(), { + args: [ + "run", + "-A", + "--import-map=https://deno.land/x/deno_pipeline/import_map.json", + "https://deno.land/x/deno_pipeline/src/dagger/runner.ts", + ], +}); + +const { stdout } = await command.output(); + +console.log(new TextDecoder().decode(stdout)); diff --git a/example/.fluentci/.fluentci/example/.fluentci/deno.json b/example/.fluentci/.fluentci/example/.fluentci/deno.json new file mode 100644 index 0000000..4240219 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/deno.json @@ -0,0 +1,9 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "ci:dagger": "dagger run deno run -A src/dagger/runner.ts" + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/deno.lock b/example/.fluentci/.fluentci/example/.fluentci/deno.lock new file mode 100644 index 0000000..f8af4c3 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/deno.lock @@ -0,0 +1,67 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts": "a34aea3753c7079de5877f592ce31f30d05d552155729ff3e695d77326405133", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://esm.sh/stringify-tree@1.1.1": "8d994a105481fa944515323d89bd2596c1de79f3d9bd1386266463934716eca0", + "https://esm.sh/v128/*@dagger.io/dagger@0.6.3": "cb691a77c0cdaee22f2b8393731b5143c83ce22dbbea204cdbfd203768d15b64", + "https://esm.sh/v128/@dagger.io/dagger@0.6.3/X-ZS8q/denonext/dagger.mjs": "fd0901784d75b99615b5409c3654b5c7edfc5ba377c9e1a5a67ffff4f7d3ac32", + "https://esm.sh/v128/adm-zip@0.5.10": "d9c54d6d2dd788462781a57d923295bd79304e6fd74b242fd4b30e35b39c5dcf", + "https://esm.sh/v128/adm-zip@0.5.10/denonext/adm-zip.mjs": "07a9731547905e0ca55ae917e1969d7f6d04fb3773f906ce3306891337eb4849", + "https://esm.sh/v128/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "0569a26e7ad4b3376516cbc9b1942e10961a58030eadcea8c848e6b956eb355c", + "https://esm.sh/v128/data-uri-to-buffer@4.0.1/denonext/data-uri-to-buffer.mjs": "70ef987b1da58391495ecfad9888d996469224faf3cd996d81dc2e059feb9f31", + "https://esm.sh/v128/env-paths@3.0.0": "8400fb23319be9b30d7b40d1c865541c5b3c7726cdf9b74000bc0f1678d52ecf", + "https://esm.sh/v128/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v128/execa@7.1.1": "a40c7030df81ab0847a5d844f4c5c6420af973dff05fef88e53cbb9b8667fdc2", + "https://esm.sh/v128/execa@7.1.1/denonext/execa.mjs": "9d5943544c0df3761b52f2c095f89a03ca6c028d818a8f0475ff883b0408f154", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/fetch-blob.mjs": "0531568b36c0f6db3e9825fbb2d08dee51100eb675c2bf1d98d6971a92010721", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/file.js": "fd82828163a4e7bdc15190d8c3dbfd92f93274d05bd7f7f5ab81093e3ad7e9c2", + "https://esm.sh/v128/fetch-blob@3.2.0/denonext/from.js": "7d3258c7960755497f90879806f0b815d5e564c2ac1523238af5cb9552ff5c45", + "https://esm.sh/v128/formdata-polyfill@4.0.10/denonext/esm.min.js": "b6d65a204e81eca699d9eb6f867e9efffa42db39a8f161690915a89e5eb1766f", + "https://esm.sh/v128/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "74b00283d556b281bdfd6a669576d852f2c43702043c411985f8f8188d208c5d", + "https://esm.sh/v128/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql-tag@2.12.6": "5bfa27da9c9918fb52a01b8579891e804e0365d91118df1f2e0957a72dacdc39", + "https://esm.sh/v128/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "331d09949efc4ac60c84a69b52a7da8b333210493900e54953ae4604c9874527", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v128/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v128/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v128/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v128/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v128/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v128/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v128/minizlib@2.1.2/denonext/minizlib.mjs": "0d919b6a0c60d5a31e14d748ff9d62aeae2923b604bcc6a22f90fa4bbd400d68", + "https://esm.sh/v128/mkdirp@1.0.4/denonext/mkdirp.mjs": "ee129b32e55dd8bede6b1bbd1978f7775fa5e2720d5a7ae07bf1e8c99abd77c7", + "https://esm.sh/v128/node-color-log@10.0.2": "05a277987c64153af1252167135076155fdc6b39ca260b2bdc39750da12d2a2d", + "https://esm.sh/v128/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v128/node-domexception@1.0.0/denonext/node-domexception.mjs": "bb35ba54c1a2b35870618876c0c96310a28ae58aecff33c8eed58a582e270ff4", + "https://esm.sh/v128/node-fetch@3.3.1": "916dcee177a69fb0e46970c528cb66fcd4973488f861844c0a235bfc645b0506", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/node-fetch.mjs": "dc3a8f1f2fc9eb26d0d33e49f3750acc265d51a1a54bbd670c5d9f640b633a93", + "https://esm.sh/v128/node-fetch@3.3.1/denonext/src/utils/multipart-parser.js": "713b1b8cbafc4bfb7358debeb35d507e0d2328f0a28b8a2a7d79a3e5e4f5e5b8", + "https://esm.sh/v128/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "3540b8c2dd1430f10d580f323f3a51aa30094da27a9220cce03ce69884b163bb", + "https://esm.sh/v128/onetime@6.0.0/denonext/onetime.mjs": "6e362222575d815f37fb813168d7069dd6a0f6bb6f972ed54d1bccb0f9fb3e1b", + "https://esm.sh/v128/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v128/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v128/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v128/shebang-command@2.0.0/denonext/shebang-command.mjs": "404e0fb09a782ca9495d53c721bb84b673b7b2e1054e021852143a6b91ca0e4f", + "https://esm.sh/v128/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v128/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v128/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v128/tar@6.1.15": "0460339f8aba5f287e8bebe258fe3fe13cb12f85820693f25724f0d98ef1258e", + "https://esm.sh/v128/tar@6.1.15/denonext/tar.mjs": "6194d892de8457b3b1f11d5cbacda1d540b453b45e8cb9f5f610abfb3e490b65", + "https://esm.sh/v128/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v128/web-streams-polyfill@3.2.1/denonext/dist/ponyfill.es2018.js": "a2edb52a93494cda06386b3d6a168016b366e78f02c5eff1f94a0240be12ac96", + "https://esm.sh/v128/which@2.0.2/denonext/which.mjs": "86bf76e4937edb7fa3464d7bb9a426ef273684d1cefbec5ba5f1bdcb5cafff91", + "https://esm.sh/v128/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v130/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v130/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "40a9d40e0282b5432302a3da68b88aa11685bc0b8a0b70246168deed5c5773fe" + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..299e4c6 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by Fluent GitLab CI + +image: denoland/deno:alpine + +fmt: + image: denoland/deno:alpine + script: + - deno fmt --check + +lint: + image: denoland/deno:alpine + script: + - deno lint + +test: + image: denoland/deno:alpine + script: + - deno test + diff --git a/example/.fluentci/.fluentci/example/.fluentci/flake.lock b/example/.fluentci/.fluentci/example/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/flake.nix b/example/.fluentci/.fluentci/example/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/example/.fluentci/import_map.json b/example/.fluentci/.fluentci/example/.fluentci/import_map.json new file mode 100644 index 0000000..801ea9a --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/import_map.json @@ -0,0 +1,27 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/mod.ts b/example/.fluentci/.fluentci/example/.fluentci/mod.ts new file mode 100644 index 0000000..6152fb6 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/mod.ts @@ -0,0 +1,4 @@ +import * as GitLab from "./src/gitlab/index.ts"; +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger, GitLab }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..611a5e0 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,188 @@ +import Client from "@dagger.io/dagger"; +import { withDevbox } from "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", + deploy = "deploy", +} + +const baseCtr = (client: Client, pipeline: string) => { + if (existsSync("devbox.json")) { + return withDevbox( + client + .pipeline(pipeline) + .container() + .from("alpine:latest") + .withExec(["apk", "update"]) + .withExec(["apk", "add", "bash", "curl"]) + .withMountedCache("/nix", client.cacheVolume("nix")) + .withMountedCache("/etc/nix", client.cacheVolume("nix-etc")) + ); + } + return client.pipeline(pipeline).container().from("denoland/deno:alpine"); +}; + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.lint) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.fmt) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.test) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const deploy = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let installDeployCtl = [ + "deno", + "install", + "--allow-all", + "--no-check", + "-r", + "-f", + "https://deno.land/x/deploy/deployctl.ts", + ]; + const project = Deno.env.get("DENO_PROJECT"); + const noStatic = Deno.env.get("NO_STATIC"); + const exclude = Deno.env.get("EXCLUDE"); + + let command = ["deployctl", "deploy"]; + + if (noStatic) { + command = command.concat(["--no-static"]); + } + + if (exclude) { + command = command.concat([`--exclude=${exclude}`]); + } + + if (!Deno.env.get("DENO_DEPLOY_TOKEN")) { + throw new Error("DENO_DEPLOY_TOKEN environment variable is not set"); + } + + if (!project) { + throw new Error("DENO_PROJECT environment variable is not set"); + } + + const script = Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx"; + command = command.concat([`--project=${project}`, script]); + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + installDeployCtl = [ + "sh", + "-c", + `devbox run -- ${installDeployCtl.join(" ")}`, + ]; + } + + const ctr = baseCtr(client, Job.deploy) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withEnvVariable("PATH", "/root/.deno/bin:$PATH", { expand: true }) + .withEnvVariable("DENO_DEPLOY_TOKEN", Deno.env.get("DENO_DEPLOY_TOKEN")!) + .withEnvVariable( + "DENO_MAIN_SCRIPT", + Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx" + ) + .withExec(installDeployCtl) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, + [Job.deploy]: deploy, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", + [Job.deploy]: "Deploy your code to Deno Deploy", +}; diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts new file mode 100644 index 0000000..46be50c --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/jobs.ts @@ -0,0 +1,9 @@ +import { Job } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; + +export const fmt = new Job() + .image("denoland/deno:alpine") + .script("deno fmt --check"); + +export const lint = new Job().image("denoland/deno:alpine").script("deno lint"); + +export const test = new Job().image("denoland/deno:alpine").script("deno test"); diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts new file mode 100644 index 0000000..366de64 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline.ts @@ -0,0 +1,10 @@ +import { GitlabCI } from "https://deno.land/x/fluent_gitlab_ci@v0.3.2/mod.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +const pipeline = new GitlabCI() + .image("denoland/deno:alpine") + .addJob("fmt", fmt) + .addJob("lint", lint) + .addJob("test", test); + +export default pipeline; diff --git a/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts new file mode 100644 index 0000000..ca24710 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.fluentci/src/gitlab/pipeline_test.ts @@ -0,0 +1,8 @@ +import pipeline from "./pipeline.ts"; +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; + +Deno.test(function pipelineTest() { + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + const actual = pipeline.toString(); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/example/.vscode/settings.json b/example/.fluentci/.fluentci/example/.vscode/settings.json new file mode 100644 index 0000000..cbac569 --- /dev/null +++ b/example/.fluentci/.fluentci/example/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/example/.fluentci/.fluentci/example/README.md b/example/.fluentci/.fluentci/example/README.md new file mode 100644 index 0000000..a6193e1 --- /dev/null +++ b/example/.fluentci/.fluentci/example/README.md @@ -0,0 +1,16 @@ +# Deno Pipeline Example + +This is an example using the [Deno Pipeline](https://github.com/fluent-ci-templates/deno-pipeline). + +## ๐Ÿš€ Usage + +You need to set the following environment variables: + +- `DENO_DEPLOY_TOKEN`: Your Deno Deploy token. +- `DENO_PROJECT`: Your project name. + +Then, run the following command: + +```bash +dagger run fluentci . fmt lint deploy +``` \ No newline at end of file diff --git a/example/.fluentci/.fluentci/example/main.tsx b/example/.fluentci/.fluentci/example/main.tsx new file mode 100644 index 0000000..dd48266 --- /dev/null +++ b/example/.fluentci/.fluentci/example/main.tsx @@ -0,0 +1,20 @@ +/** @jsx h */ +import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; +import html, { h } from "https://deno.land/x/htm@0.2.1/mod.ts"; + +const handler = (req: Request) => + html({ + title: "Hello World!", + styles: [ + "html, body { margin: 0; height: 100%; }", + "body { background: #86efac; display: flex; flex-direction: column; align-items: center; justify-content: center; }", + ], + body: ( + + +

Hello Patricia!

+ + ), + }); + +serve(handler); diff --git a/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..46714d3 --- /dev/null +++ b/example/.fluentci/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,28 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_gitlab_ci + +.docker: + image: denoland/deno:alpine + services: + - docker:${DOCKER_VERSION}-dind + variables: + DOCKER_HOST: tcp://docker:2376 + DOCKER_TLS_VERIFY: "1" + DOCKER_TLS_CERTDIR: /certs + DOCKER_CERT_PATH: /certs/client + DOCKER_DRIVER: overlay2 + DOCKER_VERSION: 20.10.16 + +.dagger: + extends: .docker + before_script: + - apk add docker-cli curl unzip + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + +tests: + extends: .dagger + script: + - dagger run fluentci deno_pipeline fmt lint test + diff --git a/example/.fluentci/.fluentci/fixtures/azure-pipelines.yml b/example/.fluentci/.fluentci/fixtures/azure-pipelines.yml new file mode 100644 index 0000000..5898473 --- /dev/null +++ b/example/.fluentci/.fluentci/fixtures/azure-pipelines.yml @@ -0,0 +1,22 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_azure_pipelines + +trigger: + - main +pool: + name: Default + vmImage: ubuntu-latest +steps: + - script: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + displayName: Install Deno + - script: deno install -A -r https://cli.fluentci.io -n fluentci + displayName: Setup Fluent CI CLI + - script: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + displayName: Setup Dagger + - script: dagger run fluentci deno_pipeline fmt lint test + displayName: Run Dagger Pipelines diff --git a/example/.fluentci/.fluentci/fixtures/buildspec.yml b/example/.fluentci/.fluentci/fixtures/buildspec.yml new file mode 100644 index 0000000..f9bab4c --- /dev/null +++ b/example/.fluentci/.fluentci/fixtures/buildspec.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_aws_codepipeline + +version: 0.2 +phases: + install: + commands: + - curl -fsSL https://deno.land/x/install/install.sh | sh + - export DENO_INSTALL="$HOME/.deno" + - export PATH="$DENO_INSTALL/bin:$PATH" + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + build: + commands: + - dagger run fluentci deno_pipeline fmt lint test + post_build: + commands: + - echo Build completed on `date` diff --git a/example/.fluentci/.fluentci/fixtures/config.yml b/example/.fluentci/.fluentci/fixtures/config.yml new file mode 100644 index 0000000..164d0ba --- /dev/null +++ b/example/.fluentci/.fluentci/fixtures/config.yml @@ -0,0 +1,26 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_circleci + +version: 2.1 +jobs: + tests: + steps: + - checkout + - run: sudo apt-get update && sudo apt-get install -y curl unzip + - run: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + - run: deno install -A -r https://cli.fluentci.io -n fluentci + - run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - run: + name: Run Dagger Pipelines + command: dagger run fluentci deno_pipeline fmt lint test + machine: + image: ubuntu-2004:2023.07.1 +workflows: + dagger: + jobs: + - tests diff --git a/example/.fluentci/.fluentci/fixtures/workflow.yml b/example/.fluentci/.fluentci/fixtures/workflow.yml new file mode 100644 index 0000000..a340451 --- /dev/null +++ b/example/.fluentci/.fluentci/fixtures/workflow.yml @@ -0,0 +1,24 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Tests +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: dagger run fluentci deno_pipeline fmt lint test diff --git a/example/.fluentci/.fluentci/flake.lock b/example/.fluentci/.fluentci/flake.lock new file mode 100644 index 0000000..af7453c --- /dev/null +++ b/example/.fluentci/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1687709756, + "narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688910226, + "narHash": "sha256-kLTsFu9CAU2Gb288JhIBN/WlX4UUUDz4WiC/U59nvwk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2540432a940aee979be6ccfefba9ea0652c273a0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/.fluentci/flake.nix b/example/.fluentci/.fluentci/flake.nix new file mode 100644 index 0000000..b13ea7d --- /dev/null +++ b/example/.fluentci/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/import_map.json b/example/.fluentci/.fluentci/import_map.json new file mode 100644 index 0000000..e44a1b8 --- /dev/null +++ b/example/.fluentci/.fluentci/import_map.json @@ -0,0 +1,31 @@ +{ + "imports": { + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.6.3", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts", + "fluent_github_actions": "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts", + "fluent_circleci": "https://deno.land/x/fluent_circleci@v0.2.5/mod.ts", + "fluent_azure_pipelines": "https://deno.land/x/fluent_azure_pipelines@v0.2.0/mod.ts", + "fluent_aws_codepipeline": "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} \ No newline at end of file diff --git a/example/.fluentci/.fluentci/mod.ts b/example/.fluentci/.fluentci/mod.ts new file mode 100644 index 0000000..2c3acca --- /dev/null +++ b/example/.fluentci/.fluentci/mod.ts @@ -0,0 +1,3 @@ +import * as Dagger from "./src/dagger/index.ts"; + +export { Dagger }; diff --git a/example/.fluentci/.fluentci/src/aws/README.md b/example/.fluentci/.fluentci/src/aws/README.md new file mode 100644 index 0000000..048735a --- /dev/null +++ b/example/.fluentci/.fluentci/src/aws/README.md @@ -0,0 +1,38 @@ +# AWS CodePipeline + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +The following command will generate a `buildspec.yml` file in your project: + +```bash +fluentci ac init -t deno_pipeline fmt lint test +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_aws_codepipeline + +version: 0.2 +phases: + install: + commands: + - curl -fsSL https://deno.land/x/install/install.sh | sh + - export DENO_INSTALL="$HOME/.deno" + - export PATH="$DENO_INSTALL/bin:$PATH" + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + build: + commands: + - dagger run fluentci deno_pipeline fmt lint test + post_build: + commands: + - echo Build completed on `date` + +``` + +Feel free to edit the template generator at `.fluentci/src/aws/config.ts` to your needs. diff --git a/example/.fluentci/.fluentci/src/aws/config.ts b/example/.fluentci/.fluentci/src/aws/config.ts new file mode 100644 index 0000000..e8d46b7 --- /dev/null +++ b/example/.fluentci/.fluentci/src/aws/config.ts @@ -0,0 +1,24 @@ +import { BuildSpec } from "fluent_aws_codepipeline"; + +export function generateYaml(): BuildSpec { + const buildspec = new BuildSpec(); + buildspec + .phase("install", { + commands: [ + "curl -fsSL https://deno.land/x/install/install.sh | sh", + 'export DENO_INSTALL="$HOME/.deno"', + 'export PATH="$DENO_INSTALL/bin:$PATH"', + "deno install -A -r https://cli.fluentci.io -n fluentci", + "curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh", + "mv bin/dagger /usr/local/bin", + "dagger version", + ], + }) + .phase("build", { + commands: ["dagger run fluentci deno_pipeline fmt lint test"], + }) + .phase("post_build", { + commands: ["echo Build completed on `date`"], + }); + return buildspec; +} diff --git a/example/.fluentci/.fluentci/src/aws/config_test.ts b/example/.fluentci/.fluentci/src/aws/config_test.ts new file mode 100644 index 0000000..97bed68 --- /dev/null +++ b/example/.fluentci/.fluentci/src/aws/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateAWSCodePipelineTest() { + const buildspec = generateYaml(); + const actual = buildspec.toString(); + const expected = Deno.readTextFileSync("./fixtures/buildspec.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/src/aws/init.ts b/example/.fluentci/.fluentci/src/aws/init.ts new file mode 100644 index 0000000..83944b7 --- /dev/null +++ b/example/.fluentci/.fluentci/src/aws/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save("buildspec.yml"); diff --git a/example/.fluentci/.fluentci/src/azure/README.md b/example/.fluentci/.fluentci/src/azure/README.md new file mode 100644 index 0000000..7e7017b --- /dev/null +++ b/example/.fluentci/.fluentci/src/azure/README.md @@ -0,0 +1,41 @@ +# Azure Pipelines + +[![deno module](https://shield.deno.dev/x/codecov_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +The following command will generate a `azure-pipelines.yml` file in your project: + +```bash +fluentci ap init -t deno_pipeline +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_azure_pipelines + +trigger: + - main +pool: + name: Default + vmImage: ubuntu-latest +steps: + - script: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + displayName: Install Deno + - script: deno install -A -r https://cli.fluentci.io -n fluentci + displayName: Setup Fluent CI CLI + - script: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + displayName: Setup Dagger + - script: dagger run fluentci deno_pipeline fmt lint test + displayName: Run Dagger Pipelines + +``` + +Feel free to edit the template generator at `.fluentci/src/azure/config.ts` to your needs. diff --git a/example/.fluentci/.fluentci/src/azure/config.ts b/example/.fluentci/.fluentci/src/azure/config.ts new file mode 100644 index 0000000..537c6a6 --- /dev/null +++ b/example/.fluentci/.fluentci/src/azure/config.ts @@ -0,0 +1,41 @@ +import { AzurePipeline } from "fluent_azure_pipelines"; + +export function generateYaml(): AzurePipeline { + const azurePipeline = new AzurePipeline(); + + const installDeno = `\ + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" +`; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version +`; + + azurePipeline + .trigger(["main"]) + .pool({ + name: "Default", + vmImage: "ubuntu-latest", + }) + .step({ + script: installDeno, + displayName: "Install Deno", + }) + .step({ + script: "deno install -A -r https://cli.fluentci.io -n fluentci", + displayName: "Setup Fluent CI CLI", + }) + .step({ + script: setupDagger, + displayName: "Setup Dagger", + }) + .step({ + script: "dagger run fluentci deno_pipeline fmt lint test", + displayName: "Run Dagger Pipelines", + }); + return azurePipeline; +} diff --git a/example/.fluentci/.fluentci/src/azure/config_test.ts b/example/.fluentci/.fluentci/src/azure/config_test.ts new file mode 100644 index 0000000..0311f55 --- /dev/null +++ b/example/.fluentci/.fluentci/src/azure/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateAzurePipelinesTest() { + const azurepipelines = generateYaml(); + const actual = azurepipelines.toString(); + const expected = Deno.readTextFileSync("./fixtures/azure-pipelines.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/src/azure/init.ts b/example/.fluentci/.fluentci/src/azure/init.ts new file mode 100644 index 0000000..2e71b2e --- /dev/null +++ b/example/.fluentci/.fluentci/src/azure/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save("azure-pipeline.yml"); diff --git a/example/.fluentci/.fluentci/src/circleci/README.md b/example/.fluentci/.fluentci/src/circleci/README.md new file mode 100644 index 0000000..bbc35fb --- /dev/null +++ b/example/.fluentci/.fluentci/src/circleci/README.md @@ -0,0 +1,46 @@ +# Circle CI + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + + +The following command will generate a `.circleci/config.yml` file in your project: + +```bash +fluentci cci init -t deno_pipeline +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_circleci + +version: 2.1 +jobs: + tests: + steps: + - checkout + - run: sudo apt-get update && sudo apt-get install -y curl unzip + - run: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + - run: deno install -A -r https://cli.fluentci.io -n fluentci + - run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - run: + name: Upload Coverage + command: dagger run fluentci deno_pipeline fmt lint test + machine: + image: ubuntu-2004:2023.07.1 +workflows: + dagger: + jobs: + - tests + +``` + +Feel free to edit the template generator at `.fluentci/src/circleci/config.ts` to your needs. diff --git a/example/.fluentci/.fluentci/src/circleci/config.ts b/example/.fluentci/.fluentci/src/circleci/config.ts new file mode 100644 index 0000000..27790aa --- /dev/null +++ b/example/.fluentci/.fluentci/src/circleci/config.ts @@ -0,0 +1,37 @@ +import { CircleCI, Job } from "fluent_circleci"; + +export function generateYaml(): CircleCI { + const circleci = new CircleCI(); + + const tests = new Job().machine({ image: "ubuntu-2004:2023.07.1" }).steps([ + "checkout", + { + run: "sudo apt-get update && sudo apt-get install -y curl unzip", + }, + { + run: `\ +curl -fsSL https://deno.land/x/install/install.sh | sh +export DENO_INSTALL="$HOME/.deno" +export PATH="$DENO_INSTALL/bin:$PATH"`, + }, + { + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + run: `\ +curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh +sudo mv bin/dagger /usr/local/bin +dagger version`, + }, + { + run: { + name: "Run Dagger Pipelines", + command: "dagger run fluentci deno_pipeline fmt lint test", + }, + }, + ]); + + circleci.jobs({ tests }).workflow("dagger", ["tests"]); + + return circleci; +} diff --git a/example/.fluentci/.fluentci/src/circleci/config_test.ts b/example/.fluentci/.fluentci/src/circleci/config_test.ts new file mode 100644 index 0000000..283a9c3 --- /dev/null +++ b/example/.fluentci/.fluentci/src/circleci/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateCircleCITest() { + const circleci = generateYaml(); + const actual = circleci.toString(); + const expected = Deno.readTextFileSync("./fixtures/config.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/src/circleci/init.ts b/example/.fluentci/.fluentci/src/circleci/init.ts new file mode 100644 index 0000000..1f71248 --- /dev/null +++ b/example/.fluentci/.fluentci/src/circleci/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save(".circleci/config.yml"); diff --git a/example/.fluentci/.fluentci/src/dagger/index.ts b/example/.fluentci/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..392c001 --- /dev/null +++ b/example/.fluentci/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { fmt, lint, test } from "./jobs.ts"; + +export { fmt, lint, pipeline, test }; diff --git a/example/.fluentci/.fluentci/src/dagger/jobs.ts b/example/.fluentci/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..658ed39 --- /dev/null +++ b/example/.fluentci/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,197 @@ +import Client from "@dagger.io/dagger"; +import { upload } from "https://deno.land/x/codecov_pipeline@v0.1.0/src/dagger/jobs.ts"; +import { withDevbox } from "https://deno.land/x/nix_installer_pipeline@v0.3.6/src/dagger/steps.ts"; +import { existsSync } from "fs"; + +export enum Job { + fmt = "fmt", + lint = "lint", + test = "test", + deploy = "deploy", + codecov = "codecov", +} + +const baseCtr = (client: Client, pipeline: string) => { + if (existsSync("devbox.json")) { + return withDevbox( + client + .pipeline(pipeline) + .container() + .from("alpine:latest") + .withExec(["apk", "update"]) + .withExec(["apk", "add", "bash", "curl"]) + .withMountedCache("/nix", client.cacheVolume("nix")) + .withMountedCache("/etc/nix", client.cacheVolume("nix-etc")) + ); + } + return client.pipeline(pipeline).container().from("denoland/deno:alpine"); +}; + +export const lint = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "lint"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.lint) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const fmt = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let command = ["deno", "fmt"]; + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.fmt) + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const test = async ( + client: Client, + src = ".", + options: { ignore: string[] } = { ignore: [] } +) => { + const context = client.host().directory(src); + let command = ["deno", "test", "-A", "--coverage=coverage", "--lock-write"]; + + if (options.ignore.length > 0) { + command = command.concat([`--ignore=${options.ignore.join(",")}`]); + } + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + } + + const ctr = baseCtr(client, Job.test) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withMountedCache("/root/.cache/deno", client.cacheVolume("deno-cache")) + .withExec(command) + .withExec(["sh", "-c", "deno coverage ./coverage --lcov > coverage.lcov"]); + + await ctr.file("/app/coverage.lcov").export("./coverage.lcov"); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export const deploy = async (client: Client, src = ".") => { + const context = client.host().directory(src); + let installDeployCtl = [ + "deno", + "install", + "--allow-all", + "--no-check", + "-r", + "-f", + "https://deno.land/x/deploy/deployctl.ts", + ]; + const project = Deno.env.get("DENO_PROJECT"); + const noStatic = Deno.env.get("NO_STATIC"); + const exclude = Deno.env.get("EXCLUDE"); + + let command = ["deployctl", "deploy"]; + + if (noStatic) { + command = command.concat(["--no-static"]); + } + + if (exclude) { + command = command.concat([`--exclude=${exclude}`]); + } + + if (!Deno.env.get("DENO_DEPLOY_TOKEN")) { + throw new Error("DENO_DEPLOY_TOKEN environment variable is not set"); + } + + if (!project) { + throw new Error("DENO_PROJECT environment variable is not set"); + } + + const script = Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx"; + command = command.concat([`--project=${project}`, script]); + + if (existsSync("devbox.json")) { + command = ["sh", "-c", `devbox run -- ${command.join(" ")}`]; + installDeployCtl = [ + "sh", + "-c", + `devbox run -- ${installDeployCtl.join(" ")}`, + ]; + } + + const ctr = baseCtr(client, Job.deploy) + .from("denoland/deno:alpine") + .withDirectory("/app", context, { + exclude: [".git", ".devbox", ".fluentci"], + }) + .withWorkdir("/app") + .withEnvVariable("PATH", "/root/.deno/bin:$PATH", { expand: true }) + .withEnvVariable("DENO_DEPLOY_TOKEN", Deno.env.get("DENO_DEPLOY_TOKEN")!) + .withEnvVariable( + "DENO_MAIN_SCRIPT", + Deno.env.get("DENO_MAIN_SCRIPT") || "main.tsx" + ) + .withExec(installDeployCtl) + .withExec(command); + + const result = await ctr.stdout(); + + console.log(result); +}; + +export type JobExec = ( + client: Client, + src?: string +) => + | Promise + | (( + client: Client, + src?: string, + options?: { + ignore: string[]; + } + ) => Promise); + +export const codecov = upload; + +export const runnableJobs: Record = { + [Job.fmt]: fmt, + [Job.lint]: lint, + [Job.test]: test, + [Job.deploy]: deploy, + [Job.codecov]: upload, +}; + +export const jobDescriptions: Record = { + [Job.fmt]: "Format your code", + [Job.lint]: "Lint your code", + [Job.test]: "Run your tests", + [Job.deploy]: "Deploy your code to Deno Deploy", + [Job.codecov]: "Upload your code coverage to Codecov", +}; diff --git a/example/.fluentci/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..12bb3cb --- /dev/null +++ b/example/.fluentci/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,21 @@ +import { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; +import { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; + +const tree = { + name: brightGreen("deno_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..bad7372 --- /dev/null +++ b/example/.fluentci/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,27 @@ +import Client, { connect } from "@dagger.io/dagger"; +import * as jobs from "./jobs.ts"; + +const { fmt, lint, test, runnableJobs } = jobs; + +export default function pipeline(src = ".", args: string[] = []) { + connect(async (client: Client) => { + if (args.length > 0) { + await runSpecificJobs(client, args as jobs.Job[]); + return; + } + + await fmt(client, src); + await lint(client, src); + await test(client, src); + }); +} + +async function runSpecificJobs(client: Client, args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(client); + } +} diff --git a/example/.fluentci/.fluentci/src/dagger/runner.ts b/example/.fluentci/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..e23879e --- /dev/null +++ b/example/.fluentci/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +pipeline(".", Deno.args); diff --git a/example/.fluentci/.fluentci/src/github/README.md b/example/.fluentci/.fluentci/src/github/README.md new file mode 100644 index 0000000..00646d5 --- /dev/null +++ b/example/.fluentci/.fluentci/src/github/README.md @@ -0,0 +1,48 @@ +# Github Actions + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +The following command will generate a `.github/workflows/ci.yml` file in your project: + +```bash +fluentci gh init -t deno_pipeline +``` + +Or, if you already have a `.fluentci` folder (generated from `fluentci init -t deno`) in your project: + +```bash +fluentci gh init +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by Fluent Github Actions + +name: Tests +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: dagger run fluentci deno_pipeline fmt lint test +``` + +Feel free to edit the template generator at `.fluentci/src/github/config.ts` to your needs. diff --git a/example/.fluentci/.fluentci/src/github/config.ts b/example/.fluentci/.fluentci/src/github/config.ts new file mode 100644 index 0000000..f32b511 --- /dev/null +++ b/example/.fluentci/.fluentci/src/github/config.ts @@ -0,0 +1,51 @@ +import { JobSpec, Workflow } from "fluent_github_actions"; + +export function generateYaml(): Workflow { + const workflow = new Workflow("Tests"); + + const push = { + branches: ["main"], + }; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version`; + + const tests: JobSpec = { + "runs-on": "ubuntu-latest", + steps: [ + { + uses: "actions/checkout@v3", + }, + { + uses: "denoland/setup-deno@v1", + with: { + "deno-version": "v1.36", + }, + }, + { + name: "Setup Fluent CI CLI", + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + name: "Setup Dagger", + run: setupDagger, + }, + { + name: "Run Dagger Pipelines", + run: "dagger run fluentci deno_pipeline fmt lint test", + }, + { + name: "Upload coverage to Codecov", + run: "dagger run fluentci codecov_pipeline", + env: { + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}", + }, + }, + ], + }; + + workflow.on({ push }).jobs({ tests }); + return workflow; +} diff --git a/example/.fluentci/.fluentci/src/github/config_test.ts b/example/.fluentci/.fluentci/src/github/config_test.ts new file mode 100644 index 0000000..88bf54f --- /dev/null +++ b/example/.fluentci/.fluentci/src/github/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateGithubActionsWorkflowTest() { + const workflow = generateYaml(); + const actual = workflow.toString(); + const expected = Deno.readTextFileSync("./fixtures/workflow.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/src/github/init.ts b/example/.fluentci/.fluentci/src/github/init.ts new file mode 100644 index 0000000..4788c58 --- /dev/null +++ b/example/.fluentci/.fluentci/src/github/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save(".github/workflows/ci.yml"); diff --git a/example/.fluentci/.fluentci/src/gitlab/README.md b/example/.fluentci/.fluentci/src/gitlab/README.md new file mode 100644 index 0000000..c619026 --- /dev/null +++ b/example/.fluentci/.fluentci/src/gitlab/README.md @@ -0,0 +1,47 @@ +# Gitlab CI + +[![deno module](https://shield.deno.dev/x/deno_pipeline)](https://deno.land/x/deno_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/deno-pipeline)](https://codecov.io/gh/fluent-ci-templates/deno-pipeline) + +The following command will generate a `.gitlab-ci.yml` file in your project: + +```bash +fluentci gl init -t deno_pipeline +``` + +Generated file: + +```yaml + +# Do not edit this file directly. It is generated by Fluent GitLab CI + +.docker: + image: denoland/deno:alpine + services: + - docker:${DOCKER_VERSION}-dind + variables: + DOCKER_HOST: tcp://docker:2376 + DOCKER_TLS_VERIFY: "1" + DOCKER_TLS_CERTDIR: /certs + DOCKER_CERT_PATH: /certs/client + DOCKER_DRIVER: overlay2 + DOCKER_VERSION: 20.10.16 + +.dagger: + extends: .docker + before_script: + - apk add docker-cli curl unzip + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + +tests: + extends: .dagger + script: + - dagger run fluentci deno_pipeline fmt lint test + +``` + +Feel free to edit the template generator at `.fluentci/src/gitlab/config.ts` to your needs. diff --git a/example/.fluentci/.fluentci/src/gitlab/config.ts b/example/.fluentci/.fluentci/src/gitlab/config.ts new file mode 100644 index 0000000..38300e1 --- /dev/null +++ b/example/.fluentci/.fluentci/src/gitlab/config.ts @@ -0,0 +1,34 @@ +import { GitlabCI, Job } from "fluent_gitlab_ci"; + +export function generateYaml(): GitlabCI { + const docker = new Job() + .image("denoland/deno:alpine") + .services(["docker:${DOCKER_VERSION}-dind"]) + .variables({ + DOCKER_HOST: "tcp://docker:2376", + DOCKER_TLS_VERIFY: "1", + DOCKER_TLS_CERTDIR: "/certs", + DOCKER_CERT_PATH: "/certs/client", + DOCKER_DRIVER: "overlay2", + DOCKER_VERSION: "20.10.16", + }); + + const dagger = new Job().extends(".docker").beforeScript( + ` + apk add docker-cli curl unzip + deno install -A -r https://cli.fluentci.io -n fluentci + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + mv bin/dagger /usr/local/bin + dagger version + ` + ); + + const tests = new Job() + .extends(".dagger") + .script("dagger run fluentci deno_pipeline fmt lint test"); + + return new GitlabCI() + .addJob(".docker", docker) + .addJob(".dagger", dagger) + .addJob("tests", tests); +} diff --git a/example/.fluentci/.fluentci/src/gitlab/config_test.ts b/example/.fluentci/.fluentci/src/gitlab/config_test.ts new file mode 100644 index 0000000..bf5c856 --- /dev/null +++ b/example/.fluentci/.fluentci/src/gitlab/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateGitlabCITest() { + const gitlabci = generateYaml(); + const actual = gitlabci.toString(); + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/.fluentci/src/gitlab/init.ts b/example/.fluentci/.fluentci/src/gitlab/init.ts new file mode 100644 index 0000000..4da66cf --- /dev/null +++ b/example/.fluentci/.fluentci/src/gitlab/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().write(); diff --git a/example/.fluentci/.github/workflows/ci.yml b/example/.fluentci/.github/workflows/ci.yml new file mode 100644 index 0000000..608c4e7 --- /dev/null +++ b/example/.fluentci/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Tests +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: dagger run fluentci deno_pipeline fmt lint test + - name: Upload coverage to Codecov + run: dagger run fluentci codecov_pipeline + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/example/.fluentci/.github/workflows/example.yml b/example/.fluentci/.github/workflows/example.yml new file mode 100644 index 0000000..c768abe --- /dev/null +++ b/example/.fluentci/.github/workflows/example.yml @@ -0,0 +1,29 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Example +on: + push: + branches: + - main +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.37 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: | + dagger run deno run -A ../src/dagger/runner.ts config + dagger run deno run -A ../src/dagger/runner.ts image + working-directory: example + env: + TRIVY_IMAGE: snyk/snyk:alpine diff --git a/example/.fluentci/.gitignore b/example/.fluentci/.gitignore new file mode 100644 index 0000000..a2442bb --- /dev/null +++ b/example/.fluentci/.gitignore @@ -0,0 +1,2 @@ +coverage/ +coverage.lcov \ No newline at end of file diff --git a/example/.fluentci/.vscode/settings.json b/example/.fluentci/.vscode/settings.json new file mode 100644 index 0000000..4b9fb22 --- /dev/null +++ b/example/.fluentci/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} \ No newline at end of file diff --git a/example/.fluentci/CODE_OF_CONDUCT.md b/example/.fluentci/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..76bb835 --- /dev/null +++ b/example/.fluentci/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[GitHub Issues](https://github.com/fluent-ci-templates/trivy-pipeline/issues). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations \ No newline at end of file diff --git a/example/.fluentci/CONTRIBUTING.md b/example/.fluentci/CONTRIBUTING.md new file mode 100644 index 0000000..e97da7c --- /dev/null +++ b/example/.fluentci/CONTRIBUTING.md @@ -0,0 +1,53 @@ +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional +documentation, we greatly value feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests to ensure we have all the necessary +information to effectively respond to your bug report or contribution. + + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest features. + +When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already +reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: + +* A reproducible test case or series of steps +* The version of our code being used +* Any modifications you've made relevant to the bug +* Anything unusual about your environment or deployment + + +## Contributing via Pull Requests +Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: + +1. You are working against the latest source on the *master* branch. +2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request interface. +6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. + +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + + +## Finding contributions to work on +Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. + + +## Code of Conduct +This project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + + +## Licensing + +See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. \ No newline at end of file diff --git a/example/.fluentci/LICENSE b/example/.fluentci/LICENSE new file mode 100644 index 0000000..d9ab36a --- /dev/null +++ b/example/.fluentci/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example/.fluentci/README.md b/example/.fluentci/README.md new file mode 100644 index 0000000..6e57a22 --- /dev/null +++ b/example/.fluentci/README.md @@ -0,0 +1,57 @@ +# Trivy Pipeline + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + +A ready-to-use CI/CD Pipeline for scanning vulnerabilities using [Trivy](https://trivy.dev/). + +## ๐Ÿš€ Usage + +Run the following command: + +```bash +fluentci run trivy_pipeline +``` + +Or, if you want to use it as a template: + +```bash +fluentci init -t trivy +``` + +This will create a `.fluentci` folder in your project. + +Now you can run the pipeline with: + +```bash +fluentci run . +``` + +## Environment variables + +| Variable | Description | +| ----------------------- | ------------------------------------------------------------------- | +| TRIVY_IMAGE | The image to scan | +| TRIVY_SBOM_PATH | The path to the software bill of materials | +| TRIVY_EXIT_CODE | Specify exit code when any security issues are found. Defaults to 0 | + +## Jobs + +| Job | Description | +| -------- | --------------------------------------------- | +| config | Scan configuration files | +| fs | Scan a local filesystem | +| repo | Scan a repository | +| image | Scan a container image | +| sbom | Scan a software bill of materials | + +## Programmatic usage + +You can also use this pipeline programmatically: + +```ts +import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.2.0/mod.ts"; + +await fs(); +``` diff --git a/example/.fluentci/ci.ts b/example/.fluentci/ci.ts new file mode 100644 index 0000000..b4b4de4 --- /dev/null +++ b/example/.fluentci/ci.ts @@ -0,0 +1,10 @@ +import Client, { connect } from "https://sdk.fluentci.io/v0.1.9/mod.ts"; +import { fs } from "https://pkg.fluentci.io/trivy_pipeline@v0.1.0/mod.ts"; + +function pipeline(src = ".") { + connect(async (client: Client) => { + await fs(client, src); + }); +} + +pipeline(); diff --git a/example/.fluentci/dagger.json b/example/.fluentci/dagger.json new file mode 100644 index 0000000..675fa77 --- /dev/null +++ b/example/.fluentci/dagger.json @@ -0,0 +1,5 @@ +{ + "root": "", + "name": "trivy", + "sdkRuntime": "tsiry/dagger-sdk-deno" +} \ No newline at end of file diff --git a/example/.fluentci/deno.json b/example/.fluentci/deno.json new file mode 100644 index 0000000..e0e77b5 --- /dev/null +++ b/example/.fluentci/deno.json @@ -0,0 +1,31 @@ +{ + "importMap": "import_map.json", + "tasks": { + "esm:add": "deno run -A https://esm.sh/v128 add", + "esm:update": "deno run -A https://esm.sh/v128 update", + "esm:remove": "deno run -A https://esm.sh/v128 remove", + "schema": "deno run -A src/dagger/schema.ts", + "clean": "rm -rf gen schema.graphql" + }, + "fmt": { + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] + }, + "lint": { + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] + }, + "test": { + "exclude": [ + "example/", + ".fluentci/", + "gen/" + ] + } +} \ No newline at end of file diff --git a/example/.fluentci/deno.lock b/example/.fluentci/deno.lock new file mode 100644 index 0000000..2d79a93 --- /dev/null +++ b/example/.fluentci/deno.lock @@ -0,0 +1,269 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:@types/node": "npm:@types/node@18.16.19", + "npm:nexus": "npm:nexus@1.3.0_graphql@16.8.1" + }, + "npm": { + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "graphql@16.8.1": { + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "dependencies": {} + }, + "iterall@1.3.0": { + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "dependencies": {} + }, + "nexus@1.3.0_graphql@16.8.1": { + "integrity": "sha512-w/s19OiNOs0LrtP7pBmD9/FqJHvZLmCipVRt6v1PM8cRUYIbhEswyNKGHVoC4eHZGPSnD+bOf5A3+gnbt0A5/A==", + "dependencies": { + "graphql": "graphql@16.8.1", + "iterall": "iterall@1.3.0", + "tslib": "tslib@2.6.2" + } + }, + "tslib@2.6.2": { + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dependencies": {} + } + } + }, + "remote": { + "https://cdn.jsdelivr.net/gh/tsirysndr/tar@v0.1.1/deps.ts": "096395daebc7ed8a18f0484e4ffcc3a7f70e50946735f7df9611a7fcfd8272cc", + "https://cdn.jsdelivr.net/gh/tsirysndr/tar@v0.1.1/mod.ts": "e269d71c72ae68e82c1960e5db2a0c7419c97c9683ef717de0ab75d90f364713", + "https://cdn.jsdelivr.net/gh/tsirysndr/tar@v0.1.1/src/tar.ts": "9b02eaaa784b225ad7a23d2769cd492adf113ea7c11c02e3646849e98f4ae43b", + "https://deno.land/std@0.129.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.129.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617", + "https://deno.land/std@0.129.0/archive/tar.ts": "35ea1baddec7988cc4034765a2cee7613bc8074bd40940d3f5e98f63070a716a", + "https://deno.land/std@0.129.0/async/abortable.ts": "a896ac6b0d4237bd2d2d248217cfa1f0d85ccda93cb25ebda55e33850e526be6", + "https://deno.land/std@0.129.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", + "https://deno.land/std@0.129.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620", + "https://deno.land/std@0.129.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a", + "https://deno.land/std@0.129.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c", + "https://deno.land/std@0.129.0/async/mod.ts": "2240c6841157738414331f47dee09bb8c0482c5b1980b6e3234dd03515c8132f", + "https://deno.land/std@0.129.0/async/mux_async_iterator.ts": "f4d1d259b0c694d381770ddaaa4b799a94843eba80c17f4a2ec2949168e52d1e", + "https://deno.land/std@0.129.0/async/pool.ts": "97b0dd27c69544e374df857a40902e74e39532f226005543eabacb551e277082", + "https://deno.land/std@0.129.0/async/tee.ts": "1341feb1f5b1a96f8628d0f8fc07d8c43d3813423f18a63bf1b4785568d21b1f", + "https://deno.land/std@0.129.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d", + "https://deno.land/std@0.129.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9", + "https://deno.land/std@0.129.0/bytes/mod.ts": "d3b455c0dbd4804644159d1e25946ade5ee385d2359894de49e2c6101b18b7a9", + "https://deno.land/std@0.129.0/encoding/base64.ts": "c8c16b4adaa60d7a8eee047c73ece26844435e8f7f1328d74593dbb2dd58ea4f", + "https://deno.land/std@0.129.0/encoding/base64url.ts": "55f9d13df02efac10c6f96169daa3e702606a64e8aa27c0295f645f198c27130", + "https://deno.land/std@0.129.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37", + "https://deno.land/std@0.129.0/fmt/printf.ts": "e2c0f72146aed1efecf0c39ab928b26ae493a2278f670a871a0fbdcf36ff3379", + "https://deno.land/std@0.129.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f", + "https://deno.land/std@0.129.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d", + "https://deno.land/std@0.129.0/fs/ensure_file.ts": "7d353e64fee3d4d1e7c6b6726a2a5e987ba402c15fb49566309042887349c545", + "https://deno.land/std@0.129.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", + "https://deno.land/std@0.129.0/io/files.ts": "d199ef64e918a256320ba8d8d44ae91de87c9077df8f8d6cca013f1b9fbbe285", + "https://deno.land/std@0.129.0/io/readers.ts": "679471f3b9929b54393c9cd75b6bd178b4bc6d9aab5c0f1f9538f862cf4746fe", + "https://deno.land/std@0.129.0/io/util.ts": "078da53bba767bec0d45f7da44411f6dbf269e51ef7fcfea5e3714e04681c674", + "https://deno.land/std@0.129.0/node/_buffer.mjs": "f4a7df481d4eed06dc0151b833177d8ef74fc3a96dd4d2b073e690b6ced9474d", + "https://deno.land/std@0.129.0/node/_core.ts": "568d277be2e086af996cbdd599fec569f5280e9a494335ca23ad392b130d7bb9", + "https://deno.land/std@0.129.0/node/_events.mjs": "c0e3e0e290a8b81fee9d2973a529c8dcd5ebb4406782d1f91085274e2cb8490f", + "https://deno.land/std@0.129.0/node/_fixed_queue.ts": "455b3c484de48e810b13bdf95cd1658ecb1ba6bcb8b9315ffe994efcde3ba5f5", + "https://deno.land/std@0.129.0/node/_next_tick.ts": "64c361f6bca21df2a72dd77b84bd49d80d97a694dd3080703bc78f52146351d1", + "https://deno.land/std@0.129.0/node/_process/exiting.ts": "bc9694769139ffc596f962087155a8bfef10101d03423b9dcbc51ce6e1f88fce", + "https://deno.land/std@0.129.0/node/_util/_util_callbackify.ts": "79928ad80df3e469f7dcdb198118a7436d18a9f6c08bd7a4382332ad25a718cf", + "https://deno.land/std@0.129.0/node/_utils.ts": "c2c352e83c4c96f5ff994b1c8246bff2abcb21bfc3f1c06162cb3af1d201e615", + "https://deno.land/std@0.129.0/node/buffer.ts": "fbecbf3f237fa49bec96e97ecf56a7b92d48037b3d11219288e68943cc921600", + "https://deno.land/std@0.129.0/node/events.ts": "a1d40fc0dbccc944379ef968b80ea08f9fce579e88b5057fdb64e4f0812476dd", + "https://deno.land/std@0.129.0/node/internal/buffer.mjs": "6662fe7fe517329453545be34cea27a24f8ccd6d09afd4f609f11ade2b6dfca7", + "https://deno.land/std@0.129.0/node/internal/crypto/keys.ts": "16ce7b15a9fc5e4e3dee8fde75dae12f3d722558d5a1a6e65a9b4f86d64a21e9", + "https://deno.land/std@0.129.0/node/internal/crypto/util.mjs": "1de55a47fdbed6721b467a77ba48fdd1550c10b5eee77bbdb602eaffee365a5e", + "https://deno.land/std@0.129.0/node/internal/error_codes.ts": "ac03c4eae33de3a69d6c98e8678003207eecf75a6900eb847e3fea3c8c9e6d8f", + "https://deno.land/std@0.129.0/node/internal/errors.ts": "0d3a1eb03b654beb29b8354759a6902f45a840d4f957e9a3c632a24ce4c32632", + "https://deno.land/std@0.129.0/node/internal/hide_stack_frames.ts": "a91962ec84610bc7ec86022c4593cdf688156a5910c07b5bcd71994225c13a03", + "https://deno.land/std@0.129.0/node/internal/normalize_encoding.mjs": "3779ec8a7adf5d963b0224f9b85d1bc974a2ec2db0e858396b5d3c2c92138a0a", + "https://deno.land/std@0.129.0/node/internal/util.mjs": "684653b962fae84fd2bc08997291b1a50bed09b95dcfa7d35e3c4143163e879a", + "https://deno.land/std@0.129.0/node/internal/util/comparisons.ts": "680b55fe8bdf1613633bc469fa0440f43162c76dbe36af9aa2966310e1bb9f6e", + "https://deno.land/std@0.129.0/node/internal/util/debuglog.ts": "99e91bdf26f6c67861031f684817e1705a5bc300e81346585b396f413387edfb", + "https://deno.land/std@0.129.0/node/internal/util/inspect.mjs": "d1c2569c66a3dab45eec03208f22ad4351482527859c0011a28a6c797288a0aa", + "https://deno.land/std@0.129.0/node/internal/util/types.ts": "b2dacb8f1f5d28a51c4da5c5b75172b7fcf694073ce95ca141323657e18b0c60", + "https://deno.land/std@0.129.0/node/internal/validators.mjs": "a7e82eafb7deb85c332d5f8d9ffef052f46a42d4a121eada4a54232451acc49a", + "https://deno.land/std@0.129.0/node/internal_binding/_libuv_winerror.ts": "801e05c2742ae6cd42a5f0fd555a255a7308a65732551e962e5345f55eedc519", + "https://deno.land/std@0.129.0/node/internal_binding/_node.ts": "e4075ba8a37aef4eb5b592c8e3807c39cb49ca8653faf8e01a43421938076c1b", + "https://deno.land/std@0.129.0/node/internal_binding/_utils.ts": "1c50883b5751a9ea1b38951e62ed63bacfdc9d69ea665292edfa28e1b1c5bd94", + "https://deno.land/std@0.129.0/node/internal_binding/_winerror.ts": "8811d4be66f918c165370b619259c1f35e8c3e458b8539db64c704fbde0a7cd2", + "https://deno.land/std@0.129.0/node/internal_binding/buffer.ts": "722c62b85f966e0777b2d98c021b60e75d7f2c2dabc43413ef37d60dbd13a5d9", + "https://deno.land/std@0.129.0/node/internal_binding/constants.ts": "aff06aac49eda4234bd3a2b0b8e1fbfc67824e281c532ff9960831ab503014cc", + "https://deno.land/std@0.129.0/node/internal_binding/string_decoder.ts": "5cb1863763d1e9b458bc21d6f976f16d9c18b3b3f57eaf0ade120aee38fba227", + "https://deno.land/std@0.129.0/node/internal_binding/types.ts": "4c26fb74ba2e45de553c15014c916df6789529a93171e450d5afb016b4c765e7", + "https://deno.land/std@0.129.0/node/internal_binding/util.ts": "90364292e2bd598ab5d105b48ca49817b6708f2d1d9cbaf08b2b3ab5ca4c90a7", + "https://deno.land/std@0.129.0/node/internal_binding/uv.ts": "3821bc5e676d6955d68f581988c961d77dd28190aba5a9c59f16001a4deb34ba", + "https://deno.land/std@0.129.0/node/util.ts": "7fd6933b37af89a8e64d73dc6ee1732455a59e7e6d0965311fbd73cd634ea630", + "https://deno.land/std@0.129.0/node/util/types.mjs": "f9288198cacd374b41bae7e92a23179d3160f4c0eaf14e19be3a4e7057219a60", + "https://deno.land/std@0.129.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.129.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.129.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.129.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.129.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.129.0/path/mod.ts": "4275129bb766f0e475ecc5246aa35689eeade419d72a48355203f31802640be7", + "https://deno.land/std@0.129.0/path/posix.ts": "663e4a6fe30a145f56aa41a22d95114c4c5582d8b57d2d7c9ed27ad2c47636bb", + "https://deno.land/std@0.129.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.129.0/path/win32.ts": "e7bdf63e8d9982b4d8a01ef5689425c93310ece950e517476e22af10f41a136e", + "https://deno.land/std@0.129.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", + "https://deno.land/std@0.129.0/testing/_diff.ts": "9d849cd6877694152e01775b2d93f9d6b7aef7e24bfe3bfafc4d7a1ac8e9f392", + "https://deno.land/std@0.129.0/testing/asserts.ts": "0a95d9e8076dd3e7f0eeb605a67c148078b4b11f4abcd5eef115b0361b0736a2", + "https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1", + "https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118", + "https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af", + "https://deno.land/std@0.191.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/std@0.191.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.191.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.191.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/std@0.203.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", + "https://deno.land/std@0.203.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.203.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343", + "https://deno.land/std@0.203.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.203.0/path/_dirname.ts": "355e297236b2218600aee7a5301b937204c62e12da9db4b0b044993d9e658395", + "https://deno.land/std@0.203.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664", + "https://deno.land/std@0.203.0/path/_format.ts": "4a99270d6810f082e614309164fad75d6f1a483b68eed97c830a506cc589f8b4", + "https://deno.land/std@0.203.0/path/_from_file_url.ts": "6eadfae2e6f63ad9ee46b26db4a1b16583055c0392acedfb50ed2fc694b6f581", + "https://deno.land/std@0.203.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.203.0/path/_is_absolute.ts": "05dac10b5e93c63198b92e3687baa2be178df5321c527dc555266c0f4f51558c", + "https://deno.land/std@0.203.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e", + "https://deno.land/std@0.203.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81", + "https://deno.land/std@0.203.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2", + "https://deno.land/std@0.203.0/path/_parse.ts": "0f9b0ff43682dd9964eb1c4398610c4e165d8db9d3ac9d594220217adf480cfa", + "https://deno.land/std@0.203.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5", + "https://deno.land/std@0.203.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6", + "https://deno.land/std@0.203.0/path/_to_file_url.ts": "a141e4a525303e1a3a0c0571fd024552b5f3553a2af7d75d1ff3a503dcbb66d8", + "https://deno.land/std@0.203.0/path/_to_namespaced_path.ts": "0d5f4caa2ed98ef7a8786286df6af804b50e38859ae897b5b5b4c8c5930a75c8", + "https://deno.land/std@0.203.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221", + "https://deno.land/std@0.203.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930", + "https://deno.land/std@0.203.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.203.0/path/dirname.ts": "b6533f4ee4174a526dec50c279534df5345836dfdc15318400b08c62a62a39dd", + "https://deno.land/std@0.203.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf", + "https://deno.land/std@0.203.0/path/format.ts": "110270b238514dd68455a4c54956215a1aff7e37e22e4427b7771cefe1920aa5", + "https://deno.land/std@0.203.0/path/from_file_url.ts": "9f5cb58d58be14c775ec2e57fc70029ac8b17ed3bd7fe93e475b07280adde0ac", + "https://deno.land/std@0.203.0/path/glob.ts": "593e2c3573883225c25c5a21aaa8e9382a696b8e175ea20a3b6a1471ad17aaed", + "https://deno.land/std@0.203.0/path/is_absolute.ts": "0b92eb35a0a8780e9f16f16bb23655b67dace6a8e0d92d42039e518ee38103c1", + "https://deno.land/std@0.203.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8", + "https://deno.land/std@0.203.0/path/mod.ts": "6e1efb0b13121463aedb53ea51dabf5639a3172ab58c89900bbb72b486872532", + "https://deno.land/std@0.203.0/path/normalize.ts": "6ea523e0040979dd7ae2f1be5bf2083941881a252554c0f32566a18b03021955", + "https://deno.land/std@0.203.0/path/parse.ts": "be8de342bb9e1924d78dc4d93c45215c152db7bf738ec32475560424b119b394", + "https://deno.land/std@0.203.0/path/posix.ts": "0a1c1952d132323a88736d03e92bd236f3ed5f9f079e5823fae07c8d978ee61b", + "https://deno.land/std@0.203.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61", + "https://deno.land/std@0.203.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc", + "https://deno.land/std@0.203.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f", + "https://deno.land/std@0.203.0/path/to_file_url.ts": "00e6322373dd51ad109956b775e4e72e5f9fa68ce2c6b04e4af2a6eed3825d31", + "https://deno.land/std@0.203.0/path/to_namespaced_path.ts": "1b1db3055c343ab389901adfbda34e82b7386bcd1c744d54f9c1496ee0fd0c3d", + "https://deno.land/std@0.203.0/path/win32.ts": "8b3f80ef7a462511d5e8020ff490edcaa0a0d118f1b1e9da50e2916bdd73f9dd", + "https://deno.land/std@0.52.0/fmt/colors.ts": "ec9d653672a9a3c7b6eafe53c5bc797364a2db2dcf766ab649c1155fea7a80b2", + "https://deno.land/x/crc32@v0.2.0/mod.ts": "de7a3fa2d4ef24b96fc21e1cc4d2d65d1d2b1dcea92f63960e3e11bfa82df0fa", + "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts": "79cc758901d20a3573d7e3cc2db9f0a5fe56833f4d9befcedc072b94d542eec7", + "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/src/buildspec.ts": "fb07cbbf9473586cea66c0c508412080c2d4ba4e7f4ea0985661afeed445710b", + "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/src/spec.ts": "c0ce4c6e2685e23a3abdeb9fc18012253199dae355b06189d8248b052301a63e", + "https://deno.land/x/fluent_azure_pipelines@v0.2.0/mod.ts": "6f3c62419b96251dd1b5d8d6a172c0a8724a73b7feec786e540f51f0c8a0f0fd", + "https://deno.land/x/fluent_azure_pipelines@v0.2.0/src/config.ts": "619f4c64dad9b510c5788d4939a8afe013cb7dfc993dfd32f2ff4d0a2140075e", + "https://deno.land/x/fluent_azure_pipelines@v0.2.0/src/spec.ts": "cab6e4a6afb0f16e6c406cfab87264a963734720c468532c4f778228d1f1758d", + "https://deno.land/x/fluent_circleci@v0.2.5/mod.ts": "6a885bf35dbe08a7e971aa105763d724dd2a09c237b6292c9cd5de540237af37", + "https://deno.land/x/fluent_circleci@v0.2.5/src/config.ts": "d7e9902b4c2fddfa61ff6a509f3a09adee161fae9f93029dcbc8ec7a7bbd990b", + "https://deno.land/x/fluent_circleci@v0.2.5/src/job.ts": "b6ffb66ef10cf0e26460a88e1614ef864b606571e8d72376eeb09254f66a9926", + "https://deno.land/x/fluent_circleci@v0.2.5/src/spec.ts": "eda462e9ff535dbc7d3eb7e47253948d40ebaaf34d964e0931a6a25cdd823736", + "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts": "dc62b622791da77bc27f68e33cba618983a0770a9a12dcc9e0f9a61161bb90e5", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/event.ts": "d44d42356a04aea7ba64ff9e9a12090f477605c27a940bbf80aba612e4e96d1e", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/job_spec.ts": "93aa5b8b79cd8baaf875901322c4c38c27d4458439a831cb0ad86401b207a3dc", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/step_spec.ts": "b399949d1fd9c45873cdda70d82c92e3d9d96ba9a1d5749f3010a1f242b20e35", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/workflow.ts": "c9e3b7b3a59f7edff958eae8f27a8542f2a24889ea27c8aa016d0c0b0ca416c6", + "https://deno.land/x/fluent_github_actions@v0.2.1/src/workflow_spec.ts": "b5c696dc70ee3f777a565197c6a3a379d87d026e12d59942fef5b9dc72124c3a", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts": "3becefe569f5c9814dffa1b534794a42b948481753a5903fa1b48d5337206ced", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/src/environment.ts": "f12ee4fb50e5100fccec29dc1d35aa430bfe8373e84286a8ab9f7b8e178f14e3", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/src/gitlabci.ts": "ef36465c41412ae94b919cfcb80b99ec1c04536dbf42ad09cd73abf3ea4d52a6", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/src/gitlabci_spec.ts": "37f4ecef3ea414f57c54a360bc0178f5fad21b4a9db59d29d1961cd368febaed", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/src/index.ts": "b5e374a24e3bca1d6fead0861f2c1b1e09e087a17e59297263f681ee71c972fe", + "https://deno.land/x/fluent_gitlab_ci@v0.4.2/src/job.ts": "65a5be7f5816846919907aab00530044b571570a54a8a0bc967f4269a2ce99b7", + "https://deno.land/x/spinners@v1.1.2/mod.ts": "ed5b3562d4ea6c6887bc7e9844612b08a3bc3a3678ca77cc7dfdf461c362751e", + "https://deno.land/x/spinners@v1.1.2/spinner-types.ts": "c67e6962a0c738aa57b4d3ad9fe06c8c0131f93360acbf95456f2ba200fd8826", + "https://deno.land/x/spinners@v1.1.2/terminal-spinner.ts": "1cf0c38a423781734e2e538323c1992027830d741e90f0b81f532e5bc993d035", + "https://deno.land/x/spinners@v1.1.2/util.ts": "7083203bedbda2e6144a14a7dd093747a7a01e73d95637c888bae8ac22a1c58b", + "https://deno.land/x/xhr@0.3.0/mod.ts": "094aacd627fd9635cd942053bf8032b5223b909858fa9dc8ffa583752ff63b20", + "https://deno.land/x/zod@v3.22.1/ZodError.ts": "4de18ff525e75a0315f2c12066b77b5c2ae18c7c15ef7df7e165d63536fdf2ea", + "https://deno.land/x/zod@v3.22.1/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", + "https://deno.land/x/zod@v3.22.1/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", + "https://deno.land/x/zod@v3.22.1/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", + "https://deno.land/x/zod@v3.22.1/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", + "https://deno.land/x/zod@v3.22.1/helpers/parseUtil.ts": "f791e6e65a0340d85ad37d26cd7a3ba67126cd9957eac2b7163162155283abb1", + "https://deno.land/x/zod@v3.22.1/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", + "https://deno.land/x/zod@v3.22.1/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", + "https://deno.land/x/zod@v3.22.1/helpers/util.ts": "8baf19b19b2fca8424380367b90364b32503b6b71780269a6e3e67700bb02774", + "https://deno.land/x/zod@v3.22.1/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", + "https://deno.land/x/zod@v3.22.1/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", + "https://deno.land/x/zod@v3.22.1/mod.ts": "64e55237cb4410e17d968cd08975566059f27638ebb0b86048031b987ba251c4", + "https://deno.land/x/zod@v3.22.1/types.ts": "4edc1823385f446532c8c9f676d84550c6dc54b17135e34508576647d9612d0e", + "https://esm.sh/@dagger.io/dagger@0.8.4": "424bddc1457c1fc4975c978425730be068b5414e92dca7a64f2d80e2123c4719", + "https://esm.sh/graphql-tag@2.12.6": "2d8f017bc251d9e7346bafc3f3aef4b65f7fdc302c6e0d085e3359f44c893068", + "https://esm.sh/nanoid@4.0.2": "df5af492771eb7ed903cec5e5d8ff721bc75e6c09ddf9fc9263215c8497961f4", + "https://esm.sh/stringify-tree@1.1.1": "a0515b0f4fe97a6972047a588b7982592d9079e7aeac3323b0d26448a757cf84", + "https://esm.sh/v128/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v128/graphql-request@6.1.0": "17f00c323eb825811ce14e2b0e88a0c873acb666c382ac963d1edeb03e01f372", + "https://esm.sh/v128/graphql-request@6.1.0/denonext/graphql-request.mjs": "0b15f49d44489423ae6f06004725b6d050b6359da4969e6569bd6ad45065bd94", + "https://esm.sh/v128/graphql@16.7.1/denonext/graphql.mjs": "418ad7c07b0f2d687f33b6275d3b5f317f4afbef1f462f318229f458dff45416", + "https://esm.sh/v128/yaml@2.3.1": "8ef3aee065e93b03cebf8fd5a3418bc30131344b7f2b8c8ae27bf9f277416087", + "https://esm.sh/v128/yaml@2.3.1/denonext/yaml.mjs": "71f677b4bfc69271af9d98db5194e354f9a1863955e208e26d32a9ef78bd89f5", + "https://esm.sh/v131/yaml@2.3.1": "1fe2490feb3d9c6d2c71c64dbdbed90acd4164b00628b3c68a311b6731ca38b5", + "https://esm.sh/v131/yaml@2.3.1/denonext/yaml.mjs": "71f677b4bfc69271af9d98db5194e354f9a1863955e208e26d32a9ef78bd89f5", + "https://esm.sh/v132/@dagger.io/dagger@0.8.4/denonext/dagger.mjs": "a090c18168360a715fcc7ff731cc6cf940e8d08b8a5b18fa80983b47666118a9", + "https://esm.sh/v132/adm-zip@0.5.10/denonext/adm-zip.mjs": "bcdc3b866e0817ac4f1b2a3021dd0a9aafa2c65f1fd254511706b7924fa8b0b7", + "https://esm.sh/v132/chownr@2.0.0/denonext/chownr.mjs": "30b8f17084dfbe475a5052b615f706b06ddd17dca0535103340d485c6b94e952", + "https://esm.sh/v132/cross-fetch@3.1.8/denonext/cross-fetch.mjs": "8fba9e7c3fbaf0d2168beb63ce0cd21b5bfbfbd77e2fcbf8d957d533a71222f6", + "https://esm.sh/v132/cross-spawn@7.0.3/denonext/cross-spawn.mjs": "7c92cdafd952c699fe01eb7a0c29c7cc112c546068ff757cb8832fa110499f11", + "https://esm.sh/v132/env-paths@3.0.0/denonext/env-paths.mjs": "77984a05eb16450087f25060a070ed500ec546719d471143e16d976ca73ca956", + "https://esm.sh/v132/execa@7.2.0/denonext/execa.mjs": "5aa1c5a07843e56fd4ff4e0728d11941122d9f3c4bc37600971aa8e75c86d3a6", + "https://esm.sh/v132/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "18bcb6852f74c79ad50261e900a8c5daf2e7c38ce6662859e4f6f61d18daa6ed", + "https://esm.sh/v132/get-stream@6.0.1/denonext/get-stream.mjs": "a947a16f8cb3052fd654a84f8b36b40ce96b6a5acfb3ad4ab69d814bcf3351fb", + "https://esm.sh/v132/graphql-request@6.1.0/denonext/graphql-request.mjs": "796e05cc81ad339ef182de57452ffc00e9fef874df14fbba41338ca893499733", + "https://esm.sh/v132/graphql-tag@2.12.6/denonext/graphql-tag.mjs": "ca4302aabfeec9e4335103f1a3eeaf26277af50b828a3bcde7f262fcd4e98e1d", + "https://esm.sh/v132/graphql@16.8.0/denonext/graphql.mjs": "e10e0db78cbbef8215b2665e5ed46cbb28fc61ecdb560f9e8d304a610f51f5bc", + "https://esm.sh/v132/human-signals@4.3.1/denonext/human-signals.mjs": "3889110cedd907804443d018cffe0a1d892d5e7467661376caf967feff55cbe9", + "https://esm.sh/v132/is-stream@3.0.0/denonext/is-stream.mjs": "5c8b65f2fa051c4b18e88bbae11dac8bba9caf57752577d69bcea86d1f05c5b7", + "https://esm.sh/v132/isexe@2.0.0/denonext/isexe.mjs": "3cfefd270d1bfdfb864ee98dbb8f41d150cbf480925158f4a8f0ade8a9e17d6c", + "https://esm.sh/v132/lodash.flatten@4.4.0/denonext/lodash.flatten.mjs": "8e86ab607deea15cc3c1acfb5eae278ecbc5b80f24167b4e8f4c56df3278cd55", + "https://esm.sh/v132/merge-stream@2.0.0/denonext/merge-stream.mjs": "2c2af22401c294158d6bff659d157e3d2c028c218cc1bd2246534a45a4c03c61", + "https://esm.sh/v132/mimic-fn@4.0.0/denonext/mimic-fn.mjs": "10bcf0f2f20cbbba0c289ef7bf4d2422639bbc1c36c247be876afd6fe2d67138", + "https://esm.sh/v132/minipass@3.3.6/denonext/minipass.mjs": "59bbe430514455e78cb30c389b21af66efb2bf010cda071820a17d8c76d0d1cf", + "https://esm.sh/v132/minipass@5.0.0/denonext/minipass.mjs": "de0e049728f8c387b58c86439eb9d69a16b6a88756a6bc694e2fecbd7fd00401", + "https://esm.sh/v132/minizlib@2.1.2/denonext/minizlib.mjs": "2e35ea8aa6cb4caa6f9b6c5b3c8684460698c868363e134af26c28d0e76ded5f", + "https://esm.sh/v132/mkdirp@1.0.4/denonext/mkdirp.mjs": "091be31ee8a9c0f5f716b769bf81397ac70a587a5f2b0367e1e3bda26f5a8af7", + "https://esm.sh/v132/nanoid@4.0.2/denonext/nanoid.mjs": "4f26e89bc0867e6a838069435b3d75af305017d87ce5b51c9d6edc680954b52f", + "https://esm.sh/v132/node-color-log@10.0.2/denonext/node-color-log.mjs": "2504391bd0ce1dd4c2bf0ed0b839b8a3ad84c028d9dd17cc58dccd2e14dacfde", + "https://esm.sh/v132/node_fetch.js": "b11355358cf61343a3c30bd5942df60a3586d13e2c979b515164bfe851662798", + "https://esm.sh/v132/npm-run-path@5.1.0/denonext/npm-run-path.mjs": "b97d372a504bcca269c98f5d13ba0671e47230aaaaa36c3554b4a705085044df", + "https://esm.sh/v132/onetime@6.0.0/denonext/onetime.mjs": "c0be3fa6d700bb157f9a710aaf23df049f70c6a7d7e66a7d76568c5177267c51", + "https://esm.sh/v132/original-fs@1.2.0/denonext/original-fs.mjs": "2b1098818e54d2c6748ff5b0dd9ea5f6a61b4b6d0f63fb625f21773d11cfc667", + "https://esm.sh/v132/path-key@3.1.1/denonext/path-key.mjs": "add83c631278b7df9b33ae84e41142db88bb291295bcc27eb4e77a1cbdfa71d0", + "https://esm.sh/v132/path-key@4.0.0/denonext/path-key.mjs": "2c2e3922bd0e6e414fa2752ff800bdc6b9208035ce797fa22e49b859f8259417", + "https://esm.sh/v132/shebang-command@2.0.0/denonext/shebang-command.mjs": "35a3eae8fe5ccaab6598ba16e81bfc06bc1b46128028cd4cf76d63786dcd54aa", + "https://esm.sh/v132/shebang-regex@3.0.0/denonext/shebang-regex.mjs": "03983ba59dd2cba9402935e21b46d05f5249364cba9f5757aef23c6c2fea65b9", + "https://esm.sh/v132/signal-exit@3.0.7/denonext/signal-exit.mjs": "2a176e5f9b351fa8057213c627a1503d63bf308b64447ef47f1ca6fbb2a91c81", + "https://esm.sh/v132/stringify-tree@1.1.1/denonext/stringify-tree.mjs": "eaa9333a5219638ad170d12e12603ae00ae80fc8bf02cc112cfec7294e6bcb43", + "https://esm.sh/v132/strip-final-newline@3.0.0/denonext/strip-final-newline.mjs": "03d9be4e8a249d63cbbddeb2fb675a1bbbcb335283e604d4ce56c88c90e6f102", + "https://esm.sh/v132/tar@6.2.0/denonext/tar.mjs": "f55c2f94c0ba1123048c9e3fa0af3a2bebac3af5a9895610865f05ae4d0b7f58", + "https://esm.sh/v132/tslib@2.6.2/denonext/tslib.mjs": "29782bcd3139f77ec063dc5a9385c0fff4a8d0a23b6765c73d9edeb169a04bf1", + "https://esm.sh/v132/which@2.0.2/denonext/which.mjs": "7482079af785ec16137592b26d53cb2808b05979559f5d0d9d036a80c6b1636e", + "https://esm.sh/v132/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v132/yaml@2.3.1/denonext/yaml.mjs": "71f677b4bfc69271af9d98db5194e354f9a1863955e208e26d32a9ef78bd89f5", + "https://esm.sh/yaml@v2.3.1": "5471fa3592a8a9d1a4a3d8cacf54070b01aedaca82f14fdbbdd056a491db00ec", + "https://nix.fluentci.io/v0.5.1/deps.ts": "d2fee07fcb79b609f64f988990ad5d67c7bf17455f75dcbf1b3bbfa5de7c73b2", + "https://nix.fluentci.io/v0.5.1/src/dagger/steps.ts": "b766f4fa9624a032e7af884a5ca47bc666a529c4a472d38b74b55ca0d63cf81d", + "https://nix.fluentci.io/zenith/deps.ts": "a8fd3aa32faea5de2779cc6494471b4fd9588f039d199ff1a1ff1b00343aef26", + "https://nix.fluentci.io/zenith/src/dagger/steps.ts": "b766f4fa9624a032e7af884a5ca47bc666a529c4a472d38b74b55ca0d63cf81d", + "https://sdk.fluentci.io/v0.1.9/deps.ts": "1b036b7614a602b11e062a6911f26a6e2ac4e470cc74ac230125afd466cc77ea", + "https://sdk.fluentci.io/v0.1.9/mod.ts": "a3c03bdb97c5a3b998c7c9f616c7b00d4268013c3b16e8a90c1a36a85529d841", + "https://sdk.fluentci.io/v0.1.9/src/client.ts": "a8dd54861feccd11a53df39b2d45bfb3b2a8a3dff509f5700c41b517d4dff44d", + "https://sdk.fluentci.io/v0.1.9/src/connect.ts": "1bb42b4e0c5073bb2125b90f1d7d08a66fcad9ad8c453924b944be72d3a56c98", + "https://sdk.fluentci.io/v0.1.9/src/context.ts": "2939ff58d0a79d7377d5553e725c9a2110a0013035a5a57abe9a9a5da975c4ce", + "https://sdk.fluentci.io/v0.1.9/src/utils.ts": "394d131cfd465f0f3d8f876237f3bad1ab4dba73b9b7a396ee705d02aee40c16", + "https://sdk.fluentci.io/z1/deps.ts": "1b036b7614a602b11e062a6911f26a6e2ac4e470cc74ac230125afd466cc77ea", + "https://sdk.fluentci.io/z1/mod.ts": "261ba81a4728f5def4e327a5cd80664ea8449515a2f4eea5f3f416acae39a1fa", + "https://sdk.fluentci.io/z1/src/client.ts": "dde6d20c41df43e5bb7763782eb3702a8d830a827444d1fb388fc574b2e6a64c", + "https://sdk.fluentci.io/z1/src/connect.ts": "4aff111c403cf78672384a10214a9885e08319dde579ec458f98a7bb04874101", + "https://sdk.fluentci.io/z1/src/context.ts": "2939ff58d0a79d7377d5553e725c9a2110a0013035a5a57abe9a9a5da975c4ce", + "https://sdk.fluentci.io/z1/src/utils.ts": "5dcd6d83553930502069d067ff42bc44698e22c23426fdb78630c4b39769d308" + } +} diff --git a/example/.fluentci/deps.ts b/example/.fluentci/deps.ts new file mode 100644 index 0000000..06b55cb --- /dev/null +++ b/example/.fluentci/deps.ts @@ -0,0 +1,34 @@ +export { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import Client from "https://sdk.fluentci.io/z1/mod.ts"; +export default Client; + +export { + connect, + uploadContext, + CacheSharingMode, +} from "https://sdk.fluentci.io/z1/mod.ts"; +export { brightGreen } from "https://deno.land/std@0.191.0/fmt/colors.ts"; +export { withDevbox } from "https://nix.fluentci.io/zenith/src/dagger/steps.ts"; +export { stringifyTree } from "https://esm.sh/stringify-tree@1.1.1"; +import gql from "https://esm.sh/graphql-tag@2.12.6"; +export { gql }; + +export { + arg, + queryType, + stringArg, + intArg, + nonNull, + makeSchema, +} from "npm:nexus"; +export { + dirname, + join, + resolve, +} from "https://deno.land/std@0.203.0/path/mod.ts"; + +export * as FluentGitlabCI from "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts"; +export * as FluentGithubActions from "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts"; +export * as FluentCircleCI from "https://deno.land/x/fluent_circleci@v0.2.5/mod.ts"; +export * as FluentAzurePipelines from "https://deno.land/x/fluent_azure_pipelines@v0.2.0/mod.ts"; +export * as FluentAWSCodePipeline from "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts"; diff --git a/example/.fluentci/example/config.gql b/example/.fluentci/example/config.gql new file mode 100644 index 0000000..0d4ae22 --- /dev/null +++ b/example/.fluentci/example/config.gql @@ -0,0 +1,5 @@ +{ + trivy { + config(src: ".") + } +} diff --git a/example/.fluentci/example/dagger.json b/example/.fluentci/example/dagger.json new file mode 100644 index 0000000..675fa77 --- /dev/null +++ b/example/.fluentci/example/dagger.json @@ -0,0 +1,5 @@ +{ + "root": "", + "name": "trivy", + "sdkRuntime": "tsiry/dagger-sdk-deno" +} \ No newline at end of file diff --git a/example/.fluentci/example/image.gql b/example/.fluentci/example/image.gql new file mode 100644 index 0000000..8673c44 --- /dev/null +++ b/example/.fluentci/example/image.gql @@ -0,0 +1,5 @@ +{ + trivy { + image(src: ".") + } +} diff --git a/example/.fluentci/example/main.tf b/example/.fluentci/example/main.tf new file mode 100644 index 0000000..b0ebda9 --- /dev/null +++ b/example/.fluentci/example/main.tf @@ -0,0 +1,194 @@ +/* +Connect with friends via a shared digital space in Minecraft. + +This is a safe Minecraft server that won't break the bank. Game data is preserved across sessions. +Server is hosted on a permenant IP address. You need to start the VM each session, but it +will shutdown within 24 hours if you forget to turn it off. +Process is run in a sandboxed VM, so any server exploits cannot do any serious damage. + +We are experimenting with providing support through a [google doc](https://docs.google.com/document/d/1TXyzHKqoKMS-jY9FSMrYNLEGathqSG8YuHdj0Z9GP34). +Help us make this simple for others to use by asking for help. + + +Features +- Runs [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server/) Docker image +- Preemtible VM (cheapest), shuts down automatically within 24h if you forget to stop the VM +- Reserves a stable public IP, so the minecraft clients do not need to be reconfigured +- Reserves the disk, so game data is remembered across sessions +- Restricted service account, VM has no ability to consume GCP resources beyond its instance and disk +- 2$ per month + - Reserved IP address costs: $1.46 per month + - Reserved 10Gb disk costs: $0.40 + - VM cost: $0.01 per hour, max session cost $0.24 +*/ + +# We require a project to be provided upfront +# Create a project at https://cloud.google.com/ +# Make note of the project ID +# We need a storage bucket created upfront too to store the terraform state +terraform { + backend "gcs" { + prefix = "minecraft/state" + bucket = "terraform-larkworthy" + } +} + +# You need to fill these locals out with the project, region and zone +# Then to boot it up, run:- +# gcloud auth application-default login +# terraform init +# terraform apply +locals { + # The Google Cloud Project ID that will host and pay for your Minecraft server + project = "larkworthy-tester" + region = "europe-west1" + zone = "europe-west1-b" + # Allow members of an external Google group to turn on the server + # through the Cloud Console mobile app or https://console.cloud.google.com + # Create a group at https://groups.google.com/forum/#!creategroup + # and invite members by their email address. + enable_switch_access_group = 1 + minecraft_switch_access_group = "minecraft-switchers-lark@googlegroups.com" +} + + +provider "google" { + project = local.project + region = local.region +} + +# Create service account to run service with no permissions +resource "google_service_account" "minecraft" { + account_id = "minecraft" + display_name = "minecraft" +} + +# Permenant Minecraft disk, stays around when VM is off +resource "google_compute_disk" "minecraft" { + name = "minecraft" + type = "pd-standard" + zone = local.zone + image = "cos-cloud/cos-stable" +} + +# Permenant IP address, stays around when VM is off +resource "google_compute_address" "minecraft" { + name = "minecraft-ip" + region = local.region +} + +# VM to run Minecraft, we use preemptable which will shutdown within 24 hours +resource "google_compute_instance" "minecraft" { + name = "minecraft" + machine_type = "n1-standard-1" + zone = local.zone + tags = ["minecraft"] + deletion_protection = true + + # Run itzg/minecraft-server docker image on startup + # The instructions of https://hub.docker.com/r/itzg/minecraft-server/ are applicable + # For instance, Ssh into the instance and you can run + # docker logs mc + # docker exec -i mc rcon-cli + # Once in rcon-cli you can "op " to make someone an operator (admin) + # Use 'sudo journalctl -u google-startup-scripts.service' to retrieve the startup script output + metadata_startup_script = "docker run -d -p 25565:25565 -e EULA=TRUE -e VERSION=1.12.2 -v /var/minecraft:/data --name mc -e TYPE=FORGE -e FORGEVERSION=14.23.0.2552 -e MEMORY=2G --rm=true itzg/minecraft-server:latest;" + + metadata = { + enable-oslogin = "TRUE" + block-project-ssh-keys = true + } + + boot_disk { + auto_delete = false # Keep disk after shutdown (game data) + source = google_compute_disk.minecraft.self_link + } + + network_interface { + network = google_compute_network.minecraft.name + access_config { + nat_ip = google_compute_address.minecraft.address + } + } + + service_account { + email = google_service_account.minecraft.email + scopes = ["userinfo-email"] + } + + scheduling { + preemptible = true # Closes within 24 hours (sometimes sooner) + automatic_restart = false + } + + shielded_instance_config { + enable_integrity_monitoring = true + enable_secure_boot = true + enable_vtpm = true + } +} + +# Create a private network so the minecraft instance cannot access +# any other resources. +resource "google_compute_network" "minecraft" { + name = "minecraft" +} + +# Open the firewall for Minecraft traffic +resource "google_compute_firewall" "minecraft" { + name = "minecraft" + network = google_compute_network.minecraft.name + # Minecraft client port + allow { + protocol = "tcp" + ports = ["25565"] + } + # ICMP (ping) + allow { + protocol = "icmp" + } + # SSH (for RCON-CLI access) + allow { + protocol = "tcp" + ports = ["22"] + } + source_ranges = ["192.168.0.0/24"] + target_tags = ["minecraft"] +} + +resource "google_project_iam_custom_role" "minecraftSwitcher" { + role_id = "MinecraftSwitcher" + title = "Minecraft Switcher" + description = "Can turn a VM on and off" + permissions = ["compute.instances.start", "compute.instances.stop", "compute.instances.get"] +} + +resource "google_project_iam_custom_role" "instanceLister" { + role_id = "InstanceLister" + title = "Instance Lister" + description = "Can list VMs in project" + permissions = ["compute.instances.list"] +} + +resource "google_compute_instance_iam_member" "switcher" { + count = local.enable_switch_access_group + project = local.project + zone = local.zone + instance_name = google_compute_instance.minecraft.name + role = google_project_iam_custom_role.minecraftSwitcher.id + member = "group:${local.minecraft_switch_access_group}" +} + +resource "google_project_iam_member" "projectBrowsers" { + count = local.enable_switch_access_group + project = local.project + role = "roles/browser" + member = "group:${local.minecraft_switch_access_group}" +} + +resource "google_project_iam_member" "computeViewer" { + count = local.enable_switch_access_group + project = local.project + role = google_project_iam_custom_role.instanceLister.id + member = "group:${local.minecraft_switch_access_group}" +} diff --git a/example/.fluentci/fixtures/.gitlab-ci.yml b/example/.fluentci/fixtures/.gitlab-ci.yml new file mode 100644 index 0000000..541d5a5 --- /dev/null +++ b/example/.fluentci/fixtures/.gitlab-ci.yml @@ -0,0 +1,28 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_gitlab_ci + +.docker: + image: denoland/deno:alpine + services: + - docker:${DOCKER_VERSION}-dind + variables: + DOCKER_HOST: tcp://docker:2376 + DOCKER_TLS_VERIFY: "1" + DOCKER_TLS_CERTDIR: /certs + DOCKER_CERT_PATH: /certs/client + DOCKER_DRIVER: overlay2 + DOCKER_VERSION: 20.10.16 + +.dagger: + extends: .docker + before_script: + - apk add docker-cli curl unzip + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + +scan: + extends: .dagger + script: + - fluentci run trivy_pipeline + diff --git a/example/.fluentci/fixtures/azure-pipelines.yml b/example/.fluentci/fixtures/azure-pipelines.yml new file mode 100644 index 0000000..6fab009 --- /dev/null +++ b/example/.fluentci/fixtures/azure-pipelines.yml @@ -0,0 +1,22 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_azure_pipelines + +trigger: + - main +pool: + name: Default + vmImage: ubuntu-latest +steps: + - script: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + displayName: Install Deno + - script: deno install -A -r https://cli.fluentci.io -n fluentci + displayName: Setup Fluent CI CLI + - script: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + displayName: Setup Dagger + - script: fluentci run trivy_pipeline + displayName: Run Dagger Pipelines diff --git a/example/.fluentci/fixtures/buildspec.yml b/example/.fluentci/fixtures/buildspec.yml new file mode 100644 index 0000000..977dfb2 --- /dev/null +++ b/example/.fluentci/fixtures/buildspec.yml @@ -0,0 +1,19 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_aws_codepipeline + +version: 0.2 +phases: + install: + commands: + - curl -fsSL https://deno.land/x/install/install.sh | sh + - export DENO_INSTALL="$HOME/.deno" + - export PATH="$DENO_INSTALL/bin:$PATH" + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + build: + commands: + - fluentci run trivy_pipeline + post_build: + commands: + - echo Build completed on `date` diff --git a/example/.fluentci/fixtures/config.yml b/example/.fluentci/fixtures/config.yml new file mode 100644 index 0000000..c1a2119 --- /dev/null +++ b/example/.fluentci/fixtures/config.yml @@ -0,0 +1,26 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_circleci + +version: 2.1 +jobs: + scan: + steps: + - checkout + - run: sudo apt-get update && sudo apt-get install -y curl unzip + - run: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" + - run: deno install -A -r https://cli.fluentci.io -n fluentci + - run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - run: + name: Run Dagger Pipelines + command: fluentci run trivy_pipeline + machine: + image: ubuntu-2004:2023.07.1 +workflows: + dagger: + jobs: + - scan diff --git a/example/.fluentci/fixtures/workflow.yml b/example/.fluentci/fixtures/workflow.yml new file mode 100644 index 0000000..1e342c2 --- /dev/null +++ b/example/.fluentci/fixtures/workflow.yml @@ -0,0 +1,24 @@ +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Trivy +on: + push: + branches: + - main +jobs: + scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: fluentci run trivy_pipeline diff --git a/example/.fluentci/flake.lock b/example/.fluentci/flake.lock new file mode 100644 index 0000000..3d3e204 --- /dev/null +++ b/example/.fluentci/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1692638711, + "narHash": "sha256-J0LgSFgJVGCC1+j5R2QndadWI1oumusg6hCtYAzLID4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "91a22f76cd1716f9d0149e8a5c68424bb691de15", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/example/.fluentci/flake.nix b/example/.fluentci/flake.nix new file mode 100644 index 0000000..f304e2c --- /dev/null +++ b/example/.fluentci/flake.nix @@ -0,0 +1,26 @@ +{ + description = "A Nix-flake-based Deno development environment"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs { + inherit system; + }; + in { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.deno + ]; + }; + }); +} \ No newline at end of file diff --git a/example/.fluentci/gen/nexus.ts b/example/.fluentci/gen/nexus.ts new file mode 100644 index 0000000..93f27f4 --- /dev/null +++ b/example/.fluentci/gen/nexus.ts @@ -0,0 +1,162 @@ +/** + * This file was generated by Nexus Schema + * Do not make changes to this file directly + */ + + + + + + + +declare global { + interface NexusGen extends NexusGenTypes {} +} + +export interface NexusGenInputs { +} + +export interface NexusGenEnums { +} + +export interface NexusGenScalars { + String: string + Int: number + Float: number + Boolean: boolean + ID: string +} + +export interface NexusGenObjects { + Query: {}; +} + +export interface NexusGenInterfaces { +} + +export interface NexusGenUnions { +} + +export type NexusGenRootTypes = NexusGenObjects + +export type NexusGenAllTypes = NexusGenRootTypes & NexusGenScalars + +export interface NexusGenFieldTypes { + Query: { // field return type + config: string | null; // String + fs: string | null; // String + image: string | null; // String + repo: string | null; // String + sbom: string | null; // String + } +} + +export interface NexusGenFieldTypeNames { + Query: { // field return type name + config: 'String' + fs: 'String' + image: 'String' + repo: 'String' + sbom: 'String' + } +} + +export interface NexusGenArgTypes { + Query: { + config: { // args + exitCode: number; // Int! + src: string; // String! + } + fs: { // args + exitCode: number; // Int! + src: string; // String! + } + image: { // args + exitCode: number; // Int! + image: string; // String! + src: string; // String! + } + repo: { // args + exitCode: number; // Int! + repoUrl: string; // String! + src: string; // String! + } + sbom: { // args + exitCode: number; // Int! + path: string; // String! + src: string; // String! + } + } +} + +export interface NexusGenAbstractTypeMembers { +} + +export interface NexusGenTypeInterfaces { +} + +export type NexusGenObjectNames = keyof NexusGenObjects; + +export type NexusGenInputNames = never; + +export type NexusGenEnumNames = never; + +export type NexusGenInterfaceNames = never; + +export type NexusGenScalarNames = keyof NexusGenScalars; + +export type NexusGenUnionNames = never; + +export type NexusGenObjectsUsingAbstractStrategyIsTypeOf = never; + +export type NexusGenAbstractsUsingStrategyResolveType = never; + +export type NexusGenFeaturesConfig = { + abstractTypeStrategies: { + isTypeOf: false + resolveType: true + __typename: false + } +} + +export interface NexusGenTypes { + context: any; + inputTypes: NexusGenInputs; + rootTypes: NexusGenRootTypes; + inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars; + argTypes: NexusGenArgTypes; + fieldTypes: NexusGenFieldTypes; + fieldTypeNames: NexusGenFieldTypeNames; + allTypes: NexusGenAllTypes; + typeInterfaces: NexusGenTypeInterfaces; + objectNames: NexusGenObjectNames; + inputNames: NexusGenInputNames; + enumNames: NexusGenEnumNames; + interfaceNames: NexusGenInterfaceNames; + scalarNames: NexusGenScalarNames; + unionNames: NexusGenUnionNames; + allInputTypes: NexusGenTypes['inputNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['scalarNames']; + allOutputTypes: NexusGenTypes['objectNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['unionNames'] | NexusGenTypes['interfaceNames'] | NexusGenTypes['scalarNames']; + allNamedTypes: NexusGenTypes['allInputTypes'] | NexusGenTypes['allOutputTypes'] + abstractTypes: NexusGenTypes['interfaceNames'] | NexusGenTypes['unionNames']; + abstractTypeMembers: NexusGenAbstractTypeMembers; + objectsUsingAbstractStrategyIsTypeOf: NexusGenObjectsUsingAbstractStrategyIsTypeOf; + abstractsUsingStrategyResolveType: NexusGenAbstractsUsingStrategyResolveType; + features: NexusGenFeaturesConfig; +} + + +declare global { + interface NexusGenPluginTypeConfig { + } + interface NexusGenPluginInputTypeConfig { + } + interface NexusGenPluginFieldConfig { + } + interface NexusGenPluginInputFieldConfig { + } + interface NexusGenPluginSchemaConfig { + } + interface NexusGenPluginArgConfig { + } +} \ No newline at end of file diff --git a/example/.fluentci/import_map.json b/example/.fluentci/import_map.json new file mode 100644 index 0000000..88815c1 --- /dev/null +++ b/example/.fluentci/import_map.json @@ -0,0 +1,34 @@ +{ + "imports": { + "@fluentci.io/dagger": "https://sdk.fluentci.io/v0.1.9/mod.ts", + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.8.4", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts", + "fluent_github_actions": "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts", + "fluent_circleci": "https://deno.land/x/fluent_circleci@v0.2.5/mod.ts", + "fluent_azure_pipelines": "https://deno.land/x/fluent_azure_pipelines@v0.2.0/mod.ts", + "fluent_aws_codepipeline": "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts", + "url": "node:url", + "readline": "node:readline", + "process": "node:process", + "path": "node:path", + "os": "node:os", + "fs": "node:fs", + "crypto": "node:crypto" + }, + "scopes": { + "https://esm.sh/v128/": { + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", + "execa": "https://esm.sh/v128/execa@7.1.1", + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", + "graphql": "https://esm.sh/v128/graphql@16.7.1", + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", + "tar": "https://esm.sh/v128/tar@6.1.15" + } + } +} \ No newline at end of file diff --git a/example/.fluentci/mod.ts b/example/.fluentci/mod.ts new file mode 100644 index 0000000..52470dd --- /dev/null +++ b/example/.fluentci/mod.ts @@ -0,0 +1,3 @@ +export * from "./src/dagger/index.ts"; +export * as queries from "./src/dagger/queries.ts"; +export { schema } from "./src/dagger/schema.ts"; diff --git a/example/.fluentci/schema.graphql b/example/.fluentci/schema.graphql new file mode 100644 index 0000000..cdc7f70 --- /dev/null +++ b/example/.fluentci/schema.graphql @@ -0,0 +1,11 @@ +### This file was generated by Nexus Schema +### Do not make changes to this file directly + + +type Query { + config(exitCode: Int!, src: String!): String + fs(exitCode: Int!, src: String!): String + image(exitCode: Int!, image: String!, src: String!): String + repo(exitCode: Int!, repoUrl: String!, src: String!): String + sbom(exitCode: Int!, path: String!, src: String!): String +} \ No newline at end of file diff --git a/example/.fluentci/src/aws/README.md b/example/.fluentci/src/aws/README.md new file mode 100644 index 0000000..a614f29 --- /dev/null +++ b/example/.fluentci/src/aws/README.md @@ -0,0 +1,38 @@ +# AWS CodePipeline + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + +The following command will generate a `buildspec.yml` file in your project: + +```bash +fluentci ac init -t trivy_pipeline +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_aws_codepipeline + +version: 0.2 +phases: + install: + commands: + - curl -fsSL https://deno.land/x/install/install.sh | sh + - export trivy_INSTALL="$HOME/.deno" + - export PATH="$trivy_INSTALL/bin:$PATH" + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + build: + commands: + - fluentci run trivy_pipeline + post_build: + commands: + - echo Build completed on `date` + +``` + +Feel free to edit the template generator at `.fluentci/src/aws/config.ts` to your needs. diff --git a/example/.fluentci/src/aws/config.ts b/example/.fluentci/src/aws/config.ts new file mode 100644 index 0000000..764332d --- /dev/null +++ b/example/.fluentci/src/aws/config.ts @@ -0,0 +1,24 @@ +import { BuildSpec } from "fluent_aws_codepipeline"; + +export function generateYaml(): BuildSpec { + const buildspec = new BuildSpec(); + buildspec + .phase("install", { + commands: [ + "curl -fsSL https://deno.land/x/install/install.sh | sh", + 'export DENO_INSTALL="$HOME/.deno"', + 'export PATH="$DENO_INSTALL/bin:$PATH"', + "deno install -A -r https://cli.fluentci.io -n fluentci", + "curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh", + "mv bin/dagger /usr/local/bin", + "dagger version", + ], + }) + .phase("build", { + commands: ["fluentci run trivy_pipeline"], + }) + .phase("post_build", { + commands: ["echo Build completed on `date`"], + }); + return buildspec; +} diff --git a/example/.fluentci/src/aws/config_test.ts b/example/.fluentci/src/aws/config_test.ts new file mode 100644 index 0000000..97bed68 --- /dev/null +++ b/example/.fluentci/src/aws/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateAWSCodePipelineTest() { + const buildspec = generateYaml(); + const actual = buildspec.toString(); + const expected = Deno.readTextFileSync("./fixtures/buildspec.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/src/aws/init.ts b/example/.fluentci/src/aws/init.ts new file mode 100644 index 0000000..83944b7 --- /dev/null +++ b/example/.fluentci/src/aws/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save("buildspec.yml"); diff --git a/example/.fluentci/src/azure/README.md b/example/.fluentci/src/azure/README.md new file mode 100644 index 0000000..5e43156 --- /dev/null +++ b/example/.fluentci/src/azure/README.md @@ -0,0 +1,41 @@ +# Azure Pipelines + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + +The following command will generate a `azure-pipelines.yml` file in your project: + +```bash +fluentci ap init -t trivy_pipeline +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_azure_pipelines + +trigger: + - main +pool: + name: Default + vmImage: ubuntu-latest +steps: + - script: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export trivy_INSTALL="$HOME/.deno" + export PATH="$trivy_INSTALL/bin:$PATH" + displayName: Install Deno + - script: deno install -A -r https://cli.fluentci.io -n fluentci + displayName: Setup Fluent CI CLI + - script: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + displayName: Setup Dagger + - script: fluentci run trivy_pipeline + displayName: Run Dagger Pipelines + +``` + +Feel free to edit the template generator at `.fluentci/src/azure/config.ts` to your needs. diff --git a/example/.fluentci/src/azure/config.ts b/example/.fluentci/src/azure/config.ts new file mode 100644 index 0000000..e493b60 --- /dev/null +++ b/example/.fluentci/src/azure/config.ts @@ -0,0 +1,41 @@ +import { AzurePipeline } from "fluent_azure_pipelines"; + +export function generateYaml(): AzurePipeline { + const azurePipeline = new AzurePipeline(); + + const installDeno = `\ + curl -fsSL https://deno.land/x/install/install.sh | sh + export DENO_INSTALL="$HOME/.deno" + export PATH="$DENO_INSTALL/bin:$PATH" +`; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version +`; + + azurePipeline + .trigger(["main"]) + .pool({ + name: "Default", + vmImage: "ubuntu-latest", + }) + .step({ + script: installDeno, + displayName: "Install Deno", + }) + .step({ + script: "deno install -A -r https://cli.fluentci.io -n fluentci", + displayName: "Setup Fluent CI CLI", + }) + .step({ + script: setupDagger, + displayName: "Setup Dagger", + }) + .step({ + script: "fluentci run trivy_pipeline", + displayName: "Run Dagger Pipelines", + }); + return azurePipeline; +} diff --git a/example/.fluentci/src/azure/config_test.ts b/example/.fluentci/src/azure/config_test.ts new file mode 100644 index 0000000..0311f55 --- /dev/null +++ b/example/.fluentci/src/azure/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateAzurePipelinesTest() { + const azurepipelines = generateYaml(); + const actual = azurepipelines.toString(); + const expected = Deno.readTextFileSync("./fixtures/azure-pipelines.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/src/azure/init.ts b/example/.fluentci/src/azure/init.ts new file mode 100644 index 0000000..2e71b2e --- /dev/null +++ b/example/.fluentci/src/azure/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save("azure-pipeline.yml"); diff --git a/example/.fluentci/src/circleci/README.md b/example/.fluentci/src/circleci/README.md new file mode 100644 index 0000000..ca91866 --- /dev/null +++ b/example/.fluentci/src/circleci/README.md @@ -0,0 +1,46 @@ +# Circle CI + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + + +The following command will generate a `.circleci/config.yml` file in your project: + +```bash +fluentci cci init -t trivy_pipeline +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_circleci + +version: 2.1 +jobs: + scan: + steps: + - checkout + - run: sudo apt-get update && sudo apt-get install -y curl unzip + - run: | + curl -fsSL https://deno.land/x/install/install.sh | sh + export trivy_INSTALL="$HOME/.deno" + export PATH="$trivy_INSTALL/bin:$PATH" + - run: deno install -A -r https://cli.fluentci.io -n fluentci + - run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - run: + name: Upload Coverage + command: fluentci run trivy_pipeline + machine: + image: ubuntu-2004:2023.07.1 +workflows: + dagger: + jobs: + - scan + +``` + +Feel free to edit the template generator at `.fluentci/src/circleci/config.ts` to your needs. diff --git a/example/.fluentci/src/circleci/config.ts b/example/.fluentci/src/circleci/config.ts new file mode 100644 index 0000000..fdb075c --- /dev/null +++ b/example/.fluentci/src/circleci/config.ts @@ -0,0 +1,37 @@ +import { CircleCI, Job } from "fluent_circleci"; + +export function generateYaml(): CircleCI { + const circleci = new CircleCI(); + + const scan = new Job().machine({ image: "ubuntu-2004:2023.07.1" }).steps([ + "checkout", + { + run: "sudo apt-get update && sudo apt-get install -y curl unzip", + }, + { + run: `\ +curl -fsSL https://deno.land/x/install/install.sh | sh +export DENO_INSTALL="$HOME/.deno" +export PATH="$DENO_INSTALL/bin:$PATH"`, + }, + { + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + run: `\ +curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh +sudo mv bin/dagger /usr/local/bin +dagger version`, + }, + { + run: { + name: "Run Dagger Pipelines", + command: "fluentci run trivy_pipeline", + }, + }, + ]); + + circleci.jobs({ scan }).workflow("dagger", ["scan"]); + + return circleci; +} diff --git a/example/.fluentci/src/circleci/config_test.ts b/example/.fluentci/src/circleci/config_test.ts new file mode 100644 index 0000000..283a9c3 --- /dev/null +++ b/example/.fluentci/src/circleci/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateCircleCITest() { + const circleci = generateYaml(); + const actual = circleci.toString(); + const expected = Deno.readTextFileSync("./fixtures/config.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/src/circleci/init.ts b/example/.fluentci/src/circleci/init.ts new file mode 100644 index 0000000..1f71248 --- /dev/null +++ b/example/.fluentci/src/circleci/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save(".circleci/config.yml"); diff --git a/example/.fluentci/src/dagger/index.ts b/example/.fluentci/src/dagger/index.ts new file mode 100644 index 0000000..305a770 --- /dev/null +++ b/example/.fluentci/src/dagger/index.ts @@ -0,0 +1,4 @@ +import pipeline from "./pipeline.ts"; +import { config, fs, repo, image, sbom } from "./jobs.ts"; + +export { pipeline, config, fs, repo, image, sbom }; diff --git a/example/.fluentci/src/dagger/jobs.ts b/example/.fluentci/src/dagger/jobs.ts new file mode 100644 index 0000000..249058b --- /dev/null +++ b/example/.fluentci/src/dagger/jobs.ts @@ -0,0 +1,154 @@ +import Client, { connect } from "../../deps.ts"; + +export enum Job { + config = "config", + fs = "fs", + repo = "repo", + image = "image", + sbom = "sbom", +} + +export const exclude = [".fluentci"]; + +export const config = async (src = ".", exitCode?: number) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["config", src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.config) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; +}; + +export const fs = async (src = ".", exitCode?: number) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["fs", src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.fs) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; +}; + +export const repo = async (src = ".", exitCode?: number, repoUrl?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["repo", Deno.env.get("TRIVY_REPO_URL") || repoUrl || src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.repo) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; +}; + +export const image = async (src = ".", exitCode?: number, image?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + if (!Deno.env.has("TRIVY_IMAGE") && !image) { + throw new Error("TRIVY_IMAGE is not set"); + } + + const args = ["image", Deno.env.get("TRIVY_IMAGE") || image!]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.image) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; +}; + +export const sbom = async (src = ".", exitCode?: number, path?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + if (!Deno.env.has("TRIVY_SBOM_PATH") && !path) { + throw new Error("TRIVY_SBOM_PATH is not set"); + } + + const args = ["sbom", Deno.env.get("TRIVY_SBOM_PATH") || path!]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.config) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; +}; + +export type JobExec = ( + src?: string, + exitCode?: number +) => + | Promise + | ((src?: string, exitCode?: number, path?: string) => Promise) + | ((src?: string, exitCode?: number, repoUrl?: string) => Promise) + | ((src?: string, exitCode?: number, image?: string) => Promise); + +export const runnableJobs: Record = { + [Job.config]: config, + [Job.fs]: fs, + [Job.repo]: repo, + [Job.image]: image, + [Job.sbom]: sbom, +}; + +export const jobDescriptions: Record = { + [Job.config]: "Scan a configuration file", + [Job.fs]: "Scan a local filesystem", + [Job.repo]: "Scan a repository", + [Job.image]: "Scan a container image", + [Job.sbom]: "Scan a software bill of materials", +}; diff --git a/example/.fluentci/src/dagger/list_jobs.ts b/example/.fluentci/src/dagger/list_jobs.ts new file mode 100644 index 0000000..92d8385 --- /dev/null +++ b/example/.fluentci/src/dagger/list_jobs.ts @@ -0,0 +1,20 @@ +import { brightGreen, stringifyTree } from "../../deps.ts"; +import { runnableJobs, jobDescriptions, Job } from "./jobs.ts"; + +const tree = { + name: brightGreen("trivy_pipeline"), + children: (Object.keys(runnableJobs) as Job[]).map((job) => ({ + name: jobDescriptions[job] + ? `${brightGreen(job)} - ${jobDescriptions[job]}` + : brightGreen(job), + children: [], + })), +}; + +console.log( + stringifyTree( + tree, + (t) => t.name, + (t) => t.children + ) +); diff --git a/example/.fluentci/src/dagger/pipeline.ts b/example/.fluentci/src/dagger/pipeline.ts new file mode 100644 index 0000000..9dc7a64 --- /dev/null +++ b/example/.fluentci/src/dagger/pipeline.ts @@ -0,0 +1,26 @@ +import { uploadContext } from "../../deps.ts"; +import * as jobs from "./jobs.ts"; + +const { fs, runnableJobs, exclude } = jobs; + +export default async function pipeline(src = ".", args: string[] = []) { + if (Deno.env.has("FLUENTCI_SESSION_ID")) { + await uploadContext(src, exclude); + } + if (args.length > 0) { + await runSpecificJobs(args as jobs.Job[]); + return; + } + + await fs(src); +} + +async function runSpecificJobs(args: jobs.Job[]) { + for (const name of args) { + const job = runnableJobs[name]; + if (!job) { + throw new Error(`Job ${name} not found`); + } + await job(); + } +} diff --git a/example/.fluentci/src/dagger/queries.ts b/example/.fluentci/src/dagger/queries.ts new file mode 100644 index 0000000..ab7ce92 --- /dev/null +++ b/example/.fluentci/src/dagger/queries.ts @@ -0,0 +1,31 @@ +import { gql } from "../../deps.ts"; + +export const config = gql` + query config($src: String!, $exitCode: Int!) { + config(src: $src, exitCode: $exitCode) + } +`; + +export const fs = gql` + query fs($src: String!, $exitCode: Int!) { + fs(src: $src, exitCode: $exitCode) + } +`; + +export const repo = gql` + query repo($src: String!, $exitCode: Int!, $repoUrl: String!) { + repo(src: $src, exitCode: $exitCode, repoUrl: $repoUrl) + } +`; + +export const image = gql` + query image($src: String!, $exitCode: Int!, $image: String!) { + image(src: $src, exitCode: $exitCode, image: $image) + } +`; + +export const sbom = gql` + query sbom($src: String!, $exitCode: Int!, $path: String!) { + sbom(src: $src, exitCode: $exitCode, path: $path) + } +`; diff --git a/example/.fluentci/src/dagger/runner.ts b/example/.fluentci/src/dagger/runner.ts new file mode 100644 index 0000000..ce5e3a5 --- /dev/null +++ b/example/.fluentci/src/dagger/runner.ts @@ -0,0 +1,3 @@ +import pipeline from "./pipeline.ts"; + +await pipeline(".", Deno.args); diff --git a/example/.fluentci/src/dagger/schema.ts b/example/.fluentci/src/dagger/schema.ts new file mode 100644 index 0000000..c98a692 --- /dev/null +++ b/example/.fluentci/src/dagger/schema.ts @@ -0,0 +1,67 @@ +import { + queryType, + makeSchema, + dirname, + join, + resolve, + stringArg, + nonNull, + intArg, +} from "../../deps.ts"; + +import { config, fs, repo, image, sbom } from "./jobs.ts"; + +const Query = queryType({ + definition(t) { + t.string("config", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + }, + resolve: async (_root, args, _ctx) => + await config(args.src, args.exitCode), + }); + t.string("fs", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + }, + resolve: async (_root, args, _ctx) => await fs(args.src, args.exitCode), + }); + t.string("repo", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + repoUrl: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await repo(args.src, args.exitCode, args.repoUrl), + }); + t.string("image", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + image: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await image(args.src, args.exitCode, args.image), + }); + t.string("sbom", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + path: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await sbom(args.src, args.exitCode, args.path), + }); + }, +}); + +export const schema = makeSchema({ + types: [Query], + outputs: { + schema: resolve(join(dirname(".."), dirname(".."), "schema.graphql")), + typegen: resolve(join(dirname(".."), dirname(".."), "gen", "nexus.ts")), + }, +}); diff --git a/example/.fluentci/src/github/README.md b/example/.fluentci/src/github/README.md new file mode 100644 index 0000000..788e63c --- /dev/null +++ b/example/.fluentci/src/github/README.md @@ -0,0 +1,48 @@ +# Github Actions + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + +The following command will generate a `.github/workflows/ci.yml` file in your project: + +```bash +fluentci gh init -t trivy_pipeline +``` + +Or, if you already have a `.fluentci` folder (generated from `fluentci init -t trivy`) in your project: + +```bash +fluentci gh init +``` + +Generated file: + +```yaml +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions + +name: Trivy +on: + push: + branches: + - main +jobs: + scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: denoland/setup-deno@v1 + with: + trivy-version: v1.36 + - name: Setup Fluent CI CLI + run: deno install -A -r https://cli.fluentci.io -n fluentci + - name: Setup Dagger + run: | + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version + - name: Run Dagger Pipelines + run: fluentci run trivy_pipeline +``` + +Feel free to edit the template generator at `.fluentci/src/github/config.ts` to your needs. diff --git a/example/.fluentci/src/github/config.ts b/example/.fluentci/src/github/config.ts new file mode 100644 index 0000000..b14871e --- /dev/null +++ b/example/.fluentci/src/github/config.ts @@ -0,0 +1,45 @@ +import { JobSpec, Workflow } from "fluent_github_actions"; + +export function generateYaml(): Workflow { + const workflow = new Workflow("Trivy"); + + const push = { + branches: ["main"], + }; + + const setupDagger = `\ + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + sudo mv bin/dagger /usr/local/bin + dagger version`; + + const scan: JobSpec = { + "runs-on": "ubuntu-latest", + steps: [ + { + uses: "actions/checkout@v3", + }, + { + uses: "denoland/setup-deno@v1", + with: { + "deno-version": "v1.36", + }, + }, + { + name: "Setup Fluent CI CLI", + run: "deno install -A -r https://cli.fluentci.io -n fluentci", + }, + { + name: "Setup Dagger", + run: setupDagger, + }, + { + name: "Run Dagger Pipelines", + run: "fluentci run trivy_pipeline", + }, + ], + }; + + workflow.on({ push }).jobs({ scan }); + + return workflow; +} diff --git a/example/.fluentci/src/github/config_test.ts b/example/.fluentci/src/github/config_test.ts new file mode 100644 index 0000000..88bf54f --- /dev/null +++ b/example/.fluentci/src/github/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateGithubActionsWorkflowTest() { + const workflow = generateYaml(); + const actual = workflow.toString(); + const expected = Deno.readTextFileSync("./fixtures/workflow.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/src/github/init.ts b/example/.fluentci/src/github/init.ts new file mode 100644 index 0000000..193c8a3 --- /dev/null +++ b/example/.fluentci/src/github/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml().save(".github/workflows/trivy.yml"); diff --git a/example/.fluentci/src/gitlab/README.md b/example/.fluentci/src/gitlab/README.md new file mode 100644 index 0000000..af02350 --- /dev/null +++ b/example/.fluentci/src/gitlab/README.md @@ -0,0 +1,46 @@ +# Gitlab CI + +[![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Ftrivy_pipeline&query=%24.version)](https://pkg.fluentci.io/trivy_pipeline) +![deno compatibility](https://shield.deno.dev/deno/^1.34) +[![](https://img.shields.io/codecov/c/gh/fluent-ci-templates/trivy-pipeline)](https://codecov.io/gh/fluent-ci-templates/trivy-pipeline) + +The following command will generate a `.gitlab-ci.yml` file in your project: + +```bash +fluentci gl init -t trivy_pipeline +``` + +Generated file: + +```yaml + +# Do not edit this file directly. It is generated by https://deno.land/x/fluent_gitlab_ci + +.docker: + image: denoland/deno:alpine + services: + - docker:${DOCKER_VERSION}-dind + variables: + DOCKER_HOST: tcp://docker:2376 + DOCKER_TLS_VERIFY: "1" + DOCKER_TLS_CERTDIR: /certs + DOCKER_CERT_PATH: /certs/client + DOCKER_DRIVER: overlay2 + DOCKER_VERSION: 20.10.16 + +.dagger: + extends: .docker + before_script: + - apk add docker-cli curl unzip + - deno install -A -r https://cli.fluentci.io -n fluentci + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + - mv bin/dagger /usr/local/bin + - dagger version + +scan: + extends: .dagger + script: + - fluentci run trivy_pipeline +``` + +Feel free to edit the template generator at `.fluentci/src/gitlab/config.ts` to your needs. diff --git a/example/.fluentci/src/gitlab/config.ts b/example/.fluentci/src/gitlab/config.ts new file mode 100644 index 0000000..bb1f2b2 --- /dev/null +++ b/example/.fluentci/src/gitlab/config.ts @@ -0,0 +1,34 @@ +import { GitlabCI, Job } from "fluent_gitlab_ci"; + +export function generateYaml(): GitlabCI { + const docker = new Job() + .image("denoland/deno:alpine") + .services(["docker:${DOCKER_VERSION}-dind"]) + .variables({ + DOCKER_HOST: "tcp://docker:2376", + DOCKER_TLS_VERIFY: "1", + DOCKER_TLS_CERTDIR: "/certs", + DOCKER_CERT_PATH: "/certs/client", + DOCKER_DRIVER: "overlay2", + DOCKER_VERSION: "20.10.16", + }); + + const dagger = new Job().extends(".docker").beforeScript( + ` + apk add docker-cli curl unzip + deno install -A -r https://cli.fluentci.io -n fluentci + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.8.1 sh + mv bin/dagger /usr/local/bin + dagger version + ` + ); + + const scan = new Job() + .extends(".dagger") + .script("fluentci run trivy_pipeline"); + + return new GitlabCI() + .addJob(".docker", docker) + .addJob(".dagger", dagger) + .addJob("scan", scan); +} diff --git a/example/.fluentci/src/gitlab/config_test.ts b/example/.fluentci/src/gitlab/config_test.ts new file mode 100644 index 0000000..bf5c856 --- /dev/null +++ b/example/.fluentci/src/gitlab/config_test.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "https://deno.land/std@0.191.0/testing/asserts.ts"; +import { generateYaml } from "./config.ts"; + +Deno.test(function generateGitlabCITest() { + const gitlabci = generateYaml(); + const actual = gitlabci.toString(); + const expected = Deno.readTextFileSync("./fixtures/.gitlab-ci.yml"); + assertEquals(actual, expected); +}); diff --git a/example/.fluentci/src/gitlab/init.ts b/example/.fluentci/src/gitlab/init.ts new file mode 100644 index 0000000..6097dd5 --- /dev/null +++ b/example/.fluentci/src/gitlab/init.ts @@ -0,0 +1,3 @@ +import { generateYaml } from "./config.ts"; + +generateYaml(); diff --git a/example/config.gql b/example/config.gql new file mode 100644 index 0000000..0ad6dc1 --- /dev/null +++ b/example/config.gql @@ -0,0 +1,5 @@ +{ + trivy { + config(src: ".", exitCode: 0) + } +} diff --git a/example/dagger.json b/example/dagger.json new file mode 100644 index 0000000..675fa77 --- /dev/null +++ b/example/dagger.json @@ -0,0 +1,5 @@ +{ + "root": "", + "name": "trivy", + "sdkRuntime": "tsiry/dagger-sdk-deno" +} \ No newline at end of file diff --git a/example/image.gql b/example/image.gql new file mode 100644 index 0000000..a41a1bc --- /dev/null +++ b/example/image.gql @@ -0,0 +1,5 @@ +{ + trivy { + image(src: ".", exitCode: 0, image: "snyk/snyk:alpine") + } +} diff --git a/gen/nexus.ts b/gen/nexus.ts new file mode 100644 index 0000000..93f27f4 --- /dev/null +++ b/gen/nexus.ts @@ -0,0 +1,162 @@ +/** + * This file was generated by Nexus Schema + * Do not make changes to this file directly + */ + + + + + + + +declare global { + interface NexusGen extends NexusGenTypes {} +} + +export interface NexusGenInputs { +} + +export interface NexusGenEnums { +} + +export interface NexusGenScalars { + String: string + Int: number + Float: number + Boolean: boolean + ID: string +} + +export interface NexusGenObjects { + Query: {}; +} + +export interface NexusGenInterfaces { +} + +export interface NexusGenUnions { +} + +export type NexusGenRootTypes = NexusGenObjects + +export type NexusGenAllTypes = NexusGenRootTypes & NexusGenScalars + +export interface NexusGenFieldTypes { + Query: { // field return type + config: string | null; // String + fs: string | null; // String + image: string | null; // String + repo: string | null; // String + sbom: string | null; // String + } +} + +export interface NexusGenFieldTypeNames { + Query: { // field return type name + config: 'String' + fs: 'String' + image: 'String' + repo: 'String' + sbom: 'String' + } +} + +export interface NexusGenArgTypes { + Query: { + config: { // args + exitCode: number; // Int! + src: string; // String! + } + fs: { // args + exitCode: number; // Int! + src: string; // String! + } + image: { // args + exitCode: number; // Int! + image: string; // String! + src: string; // String! + } + repo: { // args + exitCode: number; // Int! + repoUrl: string; // String! + src: string; // String! + } + sbom: { // args + exitCode: number; // Int! + path: string; // String! + src: string; // String! + } + } +} + +export interface NexusGenAbstractTypeMembers { +} + +export interface NexusGenTypeInterfaces { +} + +export type NexusGenObjectNames = keyof NexusGenObjects; + +export type NexusGenInputNames = never; + +export type NexusGenEnumNames = never; + +export type NexusGenInterfaceNames = never; + +export type NexusGenScalarNames = keyof NexusGenScalars; + +export type NexusGenUnionNames = never; + +export type NexusGenObjectsUsingAbstractStrategyIsTypeOf = never; + +export type NexusGenAbstractsUsingStrategyResolveType = never; + +export type NexusGenFeaturesConfig = { + abstractTypeStrategies: { + isTypeOf: false + resolveType: true + __typename: false + } +} + +export interface NexusGenTypes { + context: any; + inputTypes: NexusGenInputs; + rootTypes: NexusGenRootTypes; + inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars; + argTypes: NexusGenArgTypes; + fieldTypes: NexusGenFieldTypes; + fieldTypeNames: NexusGenFieldTypeNames; + allTypes: NexusGenAllTypes; + typeInterfaces: NexusGenTypeInterfaces; + objectNames: NexusGenObjectNames; + inputNames: NexusGenInputNames; + enumNames: NexusGenEnumNames; + interfaceNames: NexusGenInterfaceNames; + scalarNames: NexusGenScalarNames; + unionNames: NexusGenUnionNames; + allInputTypes: NexusGenTypes['inputNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['scalarNames']; + allOutputTypes: NexusGenTypes['objectNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['unionNames'] | NexusGenTypes['interfaceNames'] | NexusGenTypes['scalarNames']; + allNamedTypes: NexusGenTypes['allInputTypes'] | NexusGenTypes['allOutputTypes'] + abstractTypes: NexusGenTypes['interfaceNames'] | NexusGenTypes['unionNames']; + abstractTypeMembers: NexusGenAbstractTypeMembers; + objectsUsingAbstractStrategyIsTypeOf: NexusGenObjectsUsingAbstractStrategyIsTypeOf; + abstractsUsingStrategyResolveType: NexusGenAbstractsUsingStrategyResolveType; + features: NexusGenFeaturesConfig; +} + + +declare global { + interface NexusGenPluginTypeConfig { + } + interface NexusGenPluginInputTypeConfig { + } + interface NexusGenPluginFieldConfig { + } + interface NexusGenPluginInputFieldConfig { + } + interface NexusGenPluginSchemaConfig { + } + interface NexusGenPluginArgConfig { + } +} \ No newline at end of file diff --git a/mod.ts b/mod.ts index fbc1f17..52470dd 100644 --- a/mod.ts +++ b/mod.ts @@ -1 +1,3 @@ export * from "./src/dagger/index.ts"; +export * as queries from "./src/dagger/queries.ts"; +export { schema } from "./src/dagger/schema.ts"; diff --git a/schema.graphql b/schema.graphql new file mode 100644 index 0000000..cdc7f70 --- /dev/null +++ b/schema.graphql @@ -0,0 +1,11 @@ +### This file was generated by Nexus Schema +### Do not make changes to this file directly + + +type Query { + config(exitCode: Int!, src: String!): String + fs(exitCode: Int!, src: String!): String + image(exitCode: Int!, image: String!, src: String!): String + repo(exitCode: Int!, repoUrl: String!, src: String!): String + sbom(exitCode: Int!, path: String!, src: String!): String +} \ No newline at end of file diff --git a/src/dagger/jobs.ts b/src/dagger/jobs.ts index bbcf8df..249058b 100644 --- a/src/dagger/jobs.ts +++ b/src/dagger/jobs.ts @@ -1,4 +1,4 @@ -import Client from "../../deps.ts"; +import Client, { connect } from "../../deps.ts"; export enum Job { config = "config", @@ -10,121 +10,132 @@ export enum Job { export const exclude = [".fluentci"]; -export const config = async (client: Client, src = ".") => { - const context = client.host().directory(src); - const args = ["config", src]; - const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || "0"; - args.push(`--exit-code=${TRIVY_EXIT_CODE}`); - - const ctr = client - .pipeline(Job.config) - .container() - .from("aquasec/trivy") - .withDirectory("/app", context, { exclude }) - .withWorkdir("/app") - .withExec(args); - - const result = await ctr.stdout(); - - console.log(result); +export const config = async (src = ".", exitCode?: number) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["config", src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.config) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; }; -export const fs = async (client: Client, src = ".") => { - const context = client.host().directory(src); - const args = ["fs", src]; - const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || "0"; - args.push(`--exit-code=${TRIVY_EXIT_CODE}`); - - const ctr = client - .pipeline(Job.fs) - .container() - .from("aquasec/trivy") - .withDirectory("/app", context, { exclude }) - .withWorkdir("/app") - .withExec(args); - - const result = await ctr.stdout(); - - console.log(result); +export const fs = async (src = ".", exitCode?: number) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["fs", src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.fs) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; }; -export const repo = async (client: Client, src = ".") => { - const context = client.host().directory(src); - const args = ["repo", Deno.env.get("TRIVY_REPO_URL") || src]; - const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || "0"; - args.push(`--exit-code=${TRIVY_EXIT_CODE}`); - - const ctr = client - .pipeline(Job.repo) - .container() - .from("aquasec/trivy") - .withDirectory("/app", context, { exclude }) - .withWorkdir("/app") - .withExec(args); - - const result = await ctr.stdout(); - - console.log(result); +export const repo = async (src = ".", exitCode?: number, repoUrl?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + const args = ["repo", Deno.env.get("TRIVY_REPO_URL") || repoUrl || src]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.repo) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; }; -export const image = async (client: Client, src = ".") => { - const context = client.host().directory(src); - if (!Deno.env.has("TRIVY_IMAGE")) { - throw new Error("TRIVY_IMAGE is not set"); - } - - const args = ["image", Deno.env.get("TRIVY_IMAGE")!]; - const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || "0"; - args.push(`--exit-code=${TRIVY_EXIT_CODE}`); - - const ctr = client - .pipeline(Job.image) - .container() - .from("aquasec/trivy") - .withDirectory("/app", context, { exclude }) - .withWorkdir("/app") - .withExec(args); - - const result = await ctr.stdout(); - - console.log(result); +export const image = async (src = ".", exitCode?: number, image?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + if (!Deno.env.has("TRIVY_IMAGE") && !image) { + throw new Error("TRIVY_IMAGE is not set"); + } + + const args = ["image", Deno.env.get("TRIVY_IMAGE") || image!]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.image) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; }; -export const sbom = async (client: Client, src = ".") => { - const context = client.host().directory(src); - if (!Deno.env.has("TRIVY_SBOM_PATH")) { - throw new Error("TRIVY_SBOM_PATH is not set"); - } - - const args = ["sbom", Deno.env.get("TRIVY_SBOM_PATH")!]; - const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || "0"; - args.push(`--exit-code=${TRIVY_EXIT_CODE}`); - - const ctr = client - .pipeline(Job.config) - .container() - .from("aquasec/trivy") - .withDirectory("/app", context, { exclude }) - .withWorkdir("/app") - .withExec(args); - - const result = await ctr.stdout(); - - console.log(result); +export const sbom = async (src = ".", exitCode?: number, path?: string) => { + await connect(async (client: Client) => { + const context = client.host().directory(src); + if (!Deno.env.has("TRIVY_SBOM_PATH") && !path) { + throw new Error("TRIVY_SBOM_PATH is not set"); + } + + const args = ["sbom", Deno.env.get("TRIVY_SBOM_PATH") || path!]; + const TRIVY_EXIT_CODE = Deno.env.get("TRIVY_EXIT_CODE") || exitCode || "0"; + args.push(`--exit-code=${TRIVY_EXIT_CODE}`); + + const ctr = client + .pipeline(Job.config) + .container() + .from("aquasec/trivy") + .withDirectory("/app", context, { exclude }) + .withWorkdir("/app") + .withExec(args); + + const result = await ctr.stdout(); + + console.log(result); + }); + return "Done"; }; export type JobExec = ( - client: Client, - src?: string + src?: string, + exitCode?: number ) => - | Promise - | (( - client: Client, - src?: string, - options?: { - ignore: string[]; - } - ) => Promise); + | Promise + | ((src?: string, exitCode?: number, path?: string) => Promise) + | ((src?: string, exitCode?: number, repoUrl?: string) => Promise) + | ((src?: string, exitCode?: number, image?: string) => Promise); export const runnableJobs: Record = { [Job.config]: config, diff --git a/src/dagger/pipeline.ts b/src/dagger/pipeline.ts index 0a8146b..9dc7a64 100644 --- a/src/dagger/pipeline.ts +++ b/src/dagger/pipeline.ts @@ -1,4 +1,4 @@ -import Client, { connect, uploadContext } from "../../deps.ts"; +import { uploadContext } from "../../deps.ts"; import * as jobs from "./jobs.ts"; const { fs, runnableJobs, exclude } = jobs; @@ -7,22 +7,20 @@ export default async function pipeline(src = ".", args: string[] = []) { if (Deno.env.has("FLUENTCI_SESSION_ID")) { await uploadContext(src, exclude); } - connect(async (client: Client) => { - if (args.length > 0) { - await runSpecificJobs(client, args as jobs.Job[]); - return; - } + if (args.length > 0) { + await runSpecificJobs(args as jobs.Job[]); + return; + } - await fs(client, src); - }); + await fs(src); } -async function runSpecificJobs(client: Client, args: jobs.Job[]) { +async function runSpecificJobs(args: jobs.Job[]) { for (const name of args) { const job = runnableJobs[name]; if (!job) { throw new Error(`Job ${name} not found`); } - await job(client); + await job(); } } diff --git a/src/dagger/queries.ts b/src/dagger/queries.ts new file mode 100644 index 0000000..ab7ce92 --- /dev/null +++ b/src/dagger/queries.ts @@ -0,0 +1,31 @@ +import { gql } from "../../deps.ts"; + +export const config = gql` + query config($src: String!, $exitCode: Int!) { + config(src: $src, exitCode: $exitCode) + } +`; + +export const fs = gql` + query fs($src: String!, $exitCode: Int!) { + fs(src: $src, exitCode: $exitCode) + } +`; + +export const repo = gql` + query repo($src: String!, $exitCode: Int!, $repoUrl: String!) { + repo(src: $src, exitCode: $exitCode, repoUrl: $repoUrl) + } +`; + +export const image = gql` + query image($src: String!, $exitCode: Int!, $image: String!) { + image(src: $src, exitCode: $exitCode, image: $image) + } +`; + +export const sbom = gql` + query sbom($src: String!, $exitCode: Int!, $path: String!) { + sbom(src: $src, exitCode: $exitCode, path: $path) + } +`; diff --git a/src/dagger/schema.ts b/src/dagger/schema.ts new file mode 100644 index 0000000..c98a692 --- /dev/null +++ b/src/dagger/schema.ts @@ -0,0 +1,67 @@ +import { + queryType, + makeSchema, + dirname, + join, + resolve, + stringArg, + nonNull, + intArg, +} from "../../deps.ts"; + +import { config, fs, repo, image, sbom } from "./jobs.ts"; + +const Query = queryType({ + definition(t) { + t.string("config", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + }, + resolve: async (_root, args, _ctx) => + await config(args.src, args.exitCode), + }); + t.string("fs", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + }, + resolve: async (_root, args, _ctx) => await fs(args.src, args.exitCode), + }); + t.string("repo", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + repoUrl: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await repo(args.src, args.exitCode, args.repoUrl), + }); + t.string("image", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + image: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await image(args.src, args.exitCode, args.image), + }); + t.string("sbom", { + args: { + src: nonNull(stringArg()), + exitCode: nonNull(intArg()), + path: nonNull(stringArg()), + }, + resolve: async (_root, args, _ctx) => + await sbom(args.src, args.exitCode, args.path), + }); + }, +}); + +export const schema = makeSchema({ + types: [Query], + outputs: { + schema: resolve(join(dirname(".."), dirname(".."), "schema.graphql")), + typegen: resolve(join(dirname(".."), dirname(".."), "gen", "nexus.ts")), + }, +});