Example
This example uses Option B, which requires creating a Dockerfile. You can create it by running the command touch Dockerfile
in the VS Code terminal. The image below shows a simple Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:8.0
ENV DOTNET.DockerScoutOptOut=1
COPY *.devcontainer/settings.vscode.json /root/.vscode-remote/data/Machine/setting.json
RUN apt-get update && apt-get -y install git procps
Now we have everything we need to start our project.
Start the Programming Journey
Section titled Start the Programming JourneyExample
Section titled ExampleThis tutorial starts with two scripts, each of which creates a column chart and a target folder to store the results. To better understand the file structure and the CWL workflow, the example with all files is available in an ARC. You can find it here
-
Create your scripts
exampleChart1.fsx //first example chart for creating a simple column chart,//with Chart.saveHtml, where you can define the//location where the chart should be saved.#r "nuget: Plotly.NET, 5.0.0"#r "nuget: Plotly.NET.Interactive, 5.0.0"#r "nuget: Plotly.NET.ImageExport, 6.1.0"open Plotly.NETopen Plotly.NET.Interactiveopen Systemopen System.IO//example: simple column chart for Devcontainer Tutoriallet x = 25let y = 85let combine = [|x, y|]let buildChart =Chart.Column (keysValues = combine,Name = "Example Chart for Devcontainer Tutorial")buildChart |> Chart.saveHtml (String.concat "" [|"./devcontainerTutorial/runs/execution"; "/Results/exampleChart1"|]) -
The second example Script is identical
exampleChart2.fsx //second example chart, which is identical to the one above#r "nuget: Plotly.NET, 5.0.0"#r "nuget: Plotly.NET.Interactive, 5.0.0"#r "nuget: Plotly.NET.ImageExport, 6.1.0"open Plotly.NETopen Plotly.NET.Interactiveopen Systemopen System.IO//example Chart 2 for Devocontainer tutoriallet x = 34let y = 26let combine = [| x, y|]let buildChart =Chart.Column (keysValues = combine,Name = "Example Chart for Devcontainer Tutorial")buildChart |> Chart.saveHtml (String.concat "" [|"./devcontainerTutorial/runs/execution"; "/Results/exampleChart2"|]) -
After that we need the CWL Command-Line-Tools that calls the scripts.
exampleChart1.cwl cwlVersion: v1.2class: CommandLineToolhints:DockerRequirement:dockerImageId: "devcontainertutorial"dockerFile: {$include: "./Dockerfile"}requirements:- class: InitialWorkDirRequirementlisting:- entryname: devcontainerTutorialentry: $(inputs.devcontainerTutorial)writable: true- class: EnvVarRequirementenvDef:- envName: DOTNET_NOLOGOenvValue: "true"- class: NetworkAccessnetworkAccess: truebaseCommand: [dotnet, fsi, "./devcontainerTutorial/workflows/exampleChart1.fsx"]inputs:devcontainerTutorial:type: Directoryoutputs:output_exampleChart1:type: DirectoryoutputBinding:glob: ./devcontainerTutorial/runs/execution/ResultsThis was for the Commnad-Line-Tool for first script (exampleChart1.fsx). Following is the second Command-Line-Tool for the second script (exampleChart2.fsx)
exampleChart2.cwl cwlVersion: v1.2class: CommandLineToolhints:DockerRequirement:dockerImageId: "devcontainertutorial"dockerFile: {$include: "./Dockerfile"}requirements:- class: InitialWorkDirRequirementlisting:- entryname: devcontainerTutorialentry: $(inputs.devcontainerTutorial)writable: true- class: EnvVarRequirementenvDef:- envName: DOTNET_NOLOGOenvValue: "true"- class: NetworkAccessnetworkAccess: truebaseCommand: [dotnet, fsi, "./devcontainerTutorial/workflows/exampleChart2.fsx"]inputs:devcontainerTutorial:type: Directoryoutputs:output_exampleChart2:type: DirectoryoutputBinding:glob: ./devcontainerTutorial/runs/execution/Results -
With the Command-Line-Tools we can create the CWL workflow, that calls the two Command-Line-Tools
mainWorkflow.cwl cwlVersion: v1.2class: Workflowhints:DockerRequirement:dockerImageId: "devcontainerTutorial"dockerFile: {$include: "./Dockerfile"}requirements:- class: InitialWorkDirRequirementlisting:- entryname: tutorialDevcontainerentry: $(inputs.tutorialDevcontainer)writable: true- class: MultipleInputFeatureRequirementinputs:devcontainerTutorial: Directoryfolder: stringsteps:exampleChart1:run: exampleChart1.cwlin:devcontainerTutorial: devcontainerTutorialout: [output_exampleChart1]exampleChart2:run: exampleChart2.cwlin:devcontainerTutorial: devcontainerTutorialout: [output_exampleChart2]expressionTool:run: exTool.cwlin:directory_array: [exampleChart1/output_exampleChart1, exampleChart2/output_exampleChart2]newname: folderout: [pool_directory]outputs:outputMain:type: DirectoryoutputSource: expressionTool/pool_directoryThe five scripts shown above are located in an ARC in the workflow directory. The next step is to create a run.cwl which is together with the run.yml located in the runs directory.
-
To follow the ARC specification we need to create a run.cwl in the runs directory, that is calling our main workflow. The files are then stored in the ARC as follows:
- …
Directoryworkflows
Directoryscripts
- exampleChart1.fsx
- exampleChart2.fsx
- exampleChart1.cwl
- exampleChart2.cwl
- workflow.cwl
Directoryruns
Directoryexecution
- run.cwl
- run.yml
- …
The run.cwl looks like this:
run.cwl cwlVersion: v1.2class: Workflowhints:DockerRequirement:dockerImageId: "devcontainerTutorial"dockerFile: {$include: "./Dockerfile"}requirements:- class: InitialWorkDirRequirementlisting:- entryname: tutorialDevcontainerentry: $(inputs.tutorialDevcontainer)writable: true- class: MultipleInputFeatureRequirement- class: SubworkflowFeatureRequirementinputs:devcontainerTutorial: Directoryfolder: stringsteps:mainWorkflow:run: ../../workflows/workflow.cwlin:devcontainerTutorial: devcontainerTutorialfolder: folderout: [outputMain]outputs:outputMain:type: DirectoryoutputSource: mainWorkflow/outputMain -
To finish our journey and to execute our CWL workflow we need the run.yml which is also located in the runs directory.
run.yml devcontainerTutorial:class: Directorypath: ../../folder: "Results"