Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove 'CanNotDelete' option #48

Open
wants to merge 144 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
f56cd24
Initial checkin with all files for a Single VM appliance definition.
May 10, 2017
56fed5a
Fixing File Paths
May 10, 2017
9d286c7
Added Readme.md
May 10, 2017
9fc3c1d
Merge pull request #1 from Azure/cloudapptools/appliances/singlevm
Turbonium May 11, 2017
aec2270
Single storage account appliance
May 11, 2017
13a21f8
Fix readme
May 11, 2017
801025b
Update Readme.md. Added an exmample parameters file.
May 11, 2017
ed64158
Merge pull request #2 from Azure/mikett
Turbonium May 11, 2017
7755128
adding appliance
krnese May 21, 2017
7ff60ff
Merge pull request #3 from krnese/kn
ravbhatnagar May 22, 2017
99ed523
update
krnese May 24, 2017
092c898
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jun 9, 2017
b12a0df
updating folder structure for serviceFabric sample
krnese Jun 9, 2017
c6e2b1c
added 101-storageAccount
krnese Jun 9, 2017
abceb64
Merge pull request #6 from krnese/101-storageAccount
ravbhatnagar Jun 12, 2017
4f21d5c
Merge pull request #4 from krnese/kn-update
ravbhatnagar Jun 12, 2017
021123f
Merge pull request #5 from krnese/update
ravbhatnagar Jun 12, 2017
c6752e9
update
krnese Jun 16, 2017
2be48ea
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jun 21, 2017
a69442a
Fixing format and structure :+1:
krnese Jun 21, 2017
d22f746
Merge pull request #7 from krnese/format
krnese Jun 21, 2017
ff21edb
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jun 29, 2017
86b6112
update
krnese Jun 29, 2017
293453e
Merge pull request #8 from krnese/sfupdates
krnese Jun 29, 2017
bbe8264
update1
krnese Jun 29, 2017
ee7d355
added guidance
krnese Jun 29, 2017
0a89dbb
update
krnese Jun 29, 2017
ba05607
fixing url
krnese Jun 29, 2017
51600c0
url
krnese Jun 29, 2017
6139971
fix
krnese Jun 29, 2017
59a706c
ok
krnese Jun 29, 2017
ef07fd0
update
krnese Jun 29, 2017
0e0595b
updates
krnese Jun 29, 2017
53af402
minor update
krnese Jun 29, 2017
30ca18d
Update psscript.md
bgelens Jun 29, 2017
c331fba
Merge pull request #2 from bgelens/patch-1
krnese Jun 29, 2017
00da4f9
added update
krnese Jun 29, 2017
a1a7f5e
Merge branch 'guidance' of https://github.com/krnese/azure-managedapp…
krnese Jun 29, 2017
e17f07a
updated sample and reference
krnese Jun 30, 2017
6908069
update
krnese Jun 30, 2017
8511392
added example
krnese Jun 30, 2017
b17e0a4
update
krnese Jun 30, 2017
209c62c
update
krnese Jul 5, 2017
15c34dd
Merge pull request #9 from krnese/guidance
krnese Jul 5, 2017
d630272
app update
krnese Jul 5, 2017
76eae4c
Merge pull request #10 from krnese/knupdate
krnese Jul 5, 2017
a7404e9
typo
krnese Jul 5, 2017
435c1bd
Merge pull request #11 from krnese/readme
krnese Jul 5, 2017
2f91960
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 5, 2017
dc7f3c7
update
krnese Jul 10, 2017
cc20c6c
Merge pull request #12 from krnese/validation
krnese Jul 10, 2017
c3e0546
Merge remote-tracking branch 'refs/remotes/origin/validation'
krnese Jul 10, 2017
9a47f59
updated url's
krnese Jul 10, 2017
b2b6a00
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 10, 2017
8919af5
Merge pull request #14 from krnese/update3
krnese Jul 10, 2017
6df3e4b
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 11, 2017
df3484c
updated marketplace sample
krnese Jul 11, 2017
c114285
Merge pull request #15 from krnese/update4
krnese Jul 11, 2017
782b177
fix
krnese Jul 11, 2017
3fed55b
Merge pull request #16 from krnese/update4
krnese Jul 11, 2017
219a4a4
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 11, 2017
631510d
minor update
krnese Jul 11, 2017
3018ef9
Merge pull request #17 from krnese/minorFix
krnese Jul 11, 2017
af8ca2b
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 13, 2017
8dd4fd6
updated validation
krnese Jul 13, 2017
8997bf0
Merge pull request #18 from krnese/managedRg
krnese Jul 13, 2017
d16b5df
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jul 17, 2017
da7d54d
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 1, 2017
ef14a3e
Merge branch 'master' of https://github.com/krnese/azure-managedapp-s…
krnese Sep 1, 2017
4b277e5
updated sample with keyvault
krnese Sep 6, 2017
1f6c67b
Merge pull request #20 from krnese/secret
krnese Sep 6, 2017
06f29f1
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 6, 2017
f6cd338
fixed typo
krnese Sep 6, 2017
e5acdc6
Merge pull request #21 from krnese/fix
krnese Sep 6, 2017
23b9e9d
Merge remote-tracking branch 'refs/remotes/Azure/master' into update
krnese Sep 12, 2017
da983c6
update
krnese Sep 12, 2017
41d31f3
Merge pull request #22 from krnese/update
krnese Sep 12, 2017
f4245b0
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
f350a0f
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
9e9205e
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
8a1a69f
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
515a2ca
Merge branch 'master' of https://github.com/krnese/azure-managedapp-s…
krnese Sep 12, 2017
8211ce1
update
krnese Sep 12, 2017
f66a856
Merge pull request #23 from krnese/master
krnese Sep 12, 2017
034126d
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
e34523e
update
krnese Sep 12, 2017
6dd7a01
Merge pull request #24 from krnese/documentation
krnese Sep 12, 2017
ef6199c
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 12, 2017
33f8146
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Sep 15, 2017
44f2357
Merge branch 'master' of https://github.com/krnese/azure-managedapp-s…
krnese Sep 15, 2017
228cf5e
batch1
krnese Oct 2, 2017
b5c038a
Merge pull request #25 from krnese/GAUpdate
krnese Oct 2, 2017
551a052
update
krnese Oct 2, 2017
4651713
Merge pull request #26 from krnese/GAUpdate
krnese Oct 2, 2017
1ccb8dd
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Oct 2, 2017
c40a774
batch2
krnese Oct 2, 2017
4710585
Merge pull request #27 from krnese/GAUpdate-batch2
krnese Oct 2, 2017
2bd4318
Merge remote-tracking branch 'refs/remotes/Azure/master' into GAUpdat…
krnese Oct 4, 2017
1b76eae
updated readme.
krnese Oct 4, 2017
93042f4
Merge pull request #28 from krnese/GAUpdate-batch2
krnese Oct 4, 2017
7eac1bb
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Oct 4, 2017
4677c56
psupdate
krnese Oct 4, 2017
4a58ae2
Merge pull request #29 from krnese/psUpdate
krnese Oct 4, 2017
86c4882
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Oct 5, 2017
10479ff
cliUpdate
krnese Oct 5, 2017
7f18fbf
Merge pull request #30 from krnese/cliUpdate
krnese Oct 5, 2017
d7e4654
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Oct 5, 2017
65d072b
prettify
krnese Oct 5, 2017
872f48a
Merge pull request #31 from krnese/prettify
krnese Oct 5, 2017
4c4c15c
fixed typo
krnese Oct 20, 2017
b3d1b5d
Merge pull request #32 from krnese/fix
krnese Oct 20, 2017
f210586
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Oct 24, 2017
9cb7451
Merge remote-tracking branch 'refs/remotes/Azure/master' into GA
krnese Oct 25, 2017
959d914
update vmname
krnese Oct 25, 2017
c109dda
Merge pull request #33 from krnese/GA
krnese Oct 25, 2017
8a72361
update
krnese Nov 17, 2017
b96b21d
Merge pull request #35 from krnese/gaUpdate01
krnese Nov 17, 2017
c607f19
new sample
krnese Nov 18, 2017
7948809
Merge pull request #36 from krnese/newSample
krnese Nov 18, 2017
9f0a63b
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Dec 12, 2017
6a4bf7d
Merge branch 'master' of https://github.com/krnese/azure-managedapp-s…
krnese Dec 12, 2017
d9ddfbf
update
krnese Jan 19, 2018
bbec6ea
update
krnese Jan 19, 2018
0842084
Merge pull request #40 from krnese/sfUpdate
krnese Jan 19, 2018
e61e747
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Jan 19, 2018
a415f05
single vm sample
krnese Jan 19, 2018
ea497c5
Merge pull request #41 from krnese/single-vm
krnese Jan 19, 2018
4e5ea59
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Feb 5, 2018
2550853
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Feb 12, 2018
375f839
adding sql iaas sample
krnese Feb 13, 2018
c4ef801
fix
krnese Feb 13, 2018
0eca650
adding sql IaaS sample
krnese Feb 13, 2018
3e39319
Merge pull request #42 from krnese/sqlIaas
krnese Feb 13, 2018
b592018
Merge branch 'master' of https://github.com/krnese/azure-managedapp-s…
krnese Feb 13, 2018
6396b70
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Feb 13, 2018
33721ef
update
krnese Feb 19, 2018
4b6b19c
Merge pull request #43 from krnese/update
krnese Feb 19, 2018
8d9c7ee
pulling sample
krnese Mar 2, 2018
7040fca
f
krnese Mar 2, 2018
e3dd8e4
Merge pull request #1 from krnese/pull
krnese Mar 2, 2018
80e5fd2
Merge remote-tracking branch 'refs/remotes/Azure/master'
krnese Mar 2, 2018
844cd14
pulled
krnese Mar 2, 2018
cd8714e
Merge pull request #44 from krnese/pulled
krnese Mar 2, 2018
65b6203
remove 'CanNotDelete' option
its-just-jo Mar 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions 1-contribution-guide/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Azure Managed Application samples

This repository contains all currently available Azure Managed Application samples contributed by the community. The following information is relevant to get started with contributing to this repository.

+ [**Contribution guide**](/1-contribution-guide/README.md#contribution-guide). Describes the minimal guidelines for contributing.
+ [**Best practices**](/1-contribution-guide/best-practices.md#best-practices). Best practices for improving the quality of Azure Managed Application design.
+ [**Git tutorial**](/1-contribution-guide/git-tutorial.md#git-tutorial). Step by step to get you started with Git.
+ [**Useful Tools**](/1-contribution-guide/useful-tools.md#useful-tools). Useful resources and tools for Azure development.

## Contribution guide

To make sure your Managed Application sample is added to this repository, please follow these guidelines. Any Managed Application sample that are out of compliance will be added to the **blacklist** and not be merged.

## Files, folders and naming conventions

1. Every Managed Application sample its associated files must be contained in its own **folder**. Name this folder so it represents what your Managed Application does. Usually this naming pattern looks like **appName-osName** or **level-platformCapability** (e.g. 101-managed-storage)
+ **Required** - Numbering should start at 101. 100 is reserved for things that need to be at the top.
+ **Protip** - Try to keep the name of your template folder short so that it fits inside the Github folder name column width.
2. Github uses ASCII for ordering files and folder. For consistent ordering **create all files and folders in lowercase**. The only **exception** to this guideline is the **README.md**, that should be in the format **UPPERCASE.lowercase**.
3. Include a **README.md** file that explains how the Managed Application works, and how to deploy.
+ Guidelines on the README.md file below.
4. A Managed Application needs to include the following files:
+ **mainTemplate.json** - The Resource Manager template that will deploy resources (and nested templates)
+ **createUiDefinition.json** - The user interface definition file, to generate input parameters to the customer facing template in the [Azure portal](https://portal.azure.com)
+ A generalized .zip file with all the artifacts for the Managed Application.
5. The custom scripts that are needed for successful template execution must be placed in a sub-folder called **scripts**.
6. Linked templates must be placed in a sub-folder called **nestedtemplates**.
7. Images used in the README.md must be placed in a folder called **images**.
8. an *azuredeploy.json* template which will create and initialize the Managed Application offering directly in the Azure subscription, referencing the artifacts in the reposotiry.

![alt text](./images/structure.png "Files, folders and naming conventions")

## README.md

The README.md describes your deployment. A good description helps other community members to understand your deployment. The README.md uses [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/) for formatting text. If you want to add images to your README.md file, store the images in the **images** folder. Reference the images in the README.md with a relative path (e.g. `![alt text](images/namingConvention.png "Files, folders and naming conventions")`). This ensures the link will reference the target repository if the source repository is forked. A good README.md contains the following sections

+ Deployment instructions
+ AzureDeploy/PowerShell/CLI example of automated import
+ Description of what the Managed Application will deploy
+ *Optional: Prerequisites
+ *Optional: Description on how to use the Managed Application
+ *Optional: Notes

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.
205 changes: 205 additions & 0 deletions 1-contribution-guide/best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Best practices

## In general..

+ It is a good practice to pass your Managed Application templates and UiDefinition through a JSON linter to remove extraneous commas, parenthesis, brackets that may break the deployment. Try http://jsonlint.com/ or a linter package for your favorite editing environment (Visual Studio Code, Atom, Sublime Text, Visual Studio etc.)
+ It's also a good idea to format your JSON for better readability. You can use a JSON formatter package for your local editor or [format online using this link](https://www.bing.com/search?q=json+formatter).

## The following guidelines are relevant to the Managed Application Resource Manager templates.

* Template parameters should follow **camelCasing**

Example:
````json
"parameters": {
"storagePrefixName": {
"type": "string",
"metadata": {
"description": "Specify the prefix of the storage account name"
}
}
}
````

* Minimize parameters whenever possible, this allows for a good "hello world" experience where the user doesn't have to answer a number of questions to complete a deployment. If you can use a variable or a literal, do so.

* Only provide parameters for:

* Things that are globally unique (e.g. website name). These are usually the endpoints the user will interact with post deployment, and need to be aware of. However, in many cases a unique name can be generated automatically by using the [uniqueString()](https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/#uniquestring) template language function.
* Other things a user must know to complete a workflow (e.g. admin user name on a VM)
* Secrets (e.g. admin password on a VM)
* Every template **must** include a parameter that specifies the location of the resources, and the *defaultValue* should be *resourceGroup().location*
* If you must include a parameter, define a defaultValue, unless the parameter is used for a passwords, storage account name prefix, or domain name label

* Every parameter in the template should have the **lower-case description** tag specified using the metadata property. This looks like below

````json
"parameters": {
"storageAccountType": {
"type": "string",
"metadata": {
"description": "The type of the new storage account created to store the VM disks"
}
}
}
````

* Template parameters **must not** include *allowedValues* for the following parameter types
* Vm Size
* Location


>**Note**:Use *createUiDefinition.json* for this purpose

* When nested templates or scripts are being used, the *mainTemplate.json* **must** include a variable with the uri() function with deployment().properties.templateLink.uri - to automatically resolve the URL for nested templates and scripts. The variable(s) would look similar to this:

````json
"variables": {
"nestedTemplateUrl": "[uri(deployment().properties.templateLink.uri, 'nestedtemplates/mytemplate.json')]",
"scriptsUrl": "[uri(deployment().properties.templateLink.uri, 'scripts/myscript.ps1')]"
}
````

* Template parameters **must not** include default values for parameters that represents the following types
* Storage Account Name prefix
* Domain Name Label

>**Note**: Use *createUiDefinition.json* for this purpose, to avoid conflict

* Do not create a parameter for a **storage account name**, but specify it is for **storage account name prefix**. Storage account names need to be lower case and can't contain hyphens (-) in addition to other domain name restrictions. A storage account has a limit of 24 characters. They also need to be globally unique. To prevent any validation issue configure a variables (using the expression **uniqueString** and a static value **storage**). Storage accounts with a common prefix (uniqueString) will not get clustered on the same racks.

Example:

````json
"parameters": {
"storageAccountNamePrefix": {
"type": "string",
"metadata": {
"description": "Prefix for the storage account name"
}
}
},
"variables": {
"storageAccountName": "[concat(parameters('storageAccountNamePrefix'), uniqueString('storage'))]"
},
````


* Passwords **must** be passed into parameters of type **securestring**. Do not specify a defaultValue for a parameter that is used for a password or an SSH key. Passwords must also be passed to **customScriptExtension** using the **commandToExecute** property in protectedSettings.

````json
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"version": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]"
]
},
"protectedSettings": {
"commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]"
}
}
````

>**Note**: In order to ensure that secrets which are passed as parameters to virtualMachines/extensions are encrypted, the protectedSettings property of the relevant extensions must be used.

* Using tags to add metadata to resources allows you to add additional information about your resources. A good use case for tags is adding metadata to a resource for billing detail purposes.

* You can group variables into complex objects. You can reference a value from a complex object in the format variable.subentry (e.g. `"[variables('storage').storageAccounts.type]"`). Grouping variables helps you keep track of related variables and improves readability of the template.

>**Note**: A complex object cannot contain an expression that references a value from a complex object. Define a separate variable for this purpose.

* If you include Azure management services to your Managed Application, such as Log Analytics, Azure Automation, Backup and Site Recovery, you **must** **not** use additional parameters for these resource locations. Instead, use the following pattern using variables, to place those services in the closest available Azure region to the Resource Group

````json
"logAnalyticsLocationMap": {
"eastasia": "southeastasia",
"southeastasia": "southeastasia",
"centralus": "westcentralus",
"eastus": "eastus",
"eastus2": "eastus",
"westus": "westcentralus",
"northcentralus": "westcentralus",
"southcentralus": "westcentralus",
"northeurope": "westeurope",
"westeurope": "westeurope",
"japanwest": "southeastasia",
"japaneast": "southeastasia",
"brazilsouth": "eastus",
"australiaeast": "australiasoutheast",
"australiasoutheast": "australiasoutheast",
"southindia": "southeastasia",
"centralindia": "southeastasia",
"westindia": "southeastasia",
"canadacentral": "eastus",
"canadaeast": "eastus",
"uksouth": "westeurope",
"ukwest": "westeurope",
"westcentralus": "westcentralus",
"westus2": "westcentralus",
"koreacentral": "southeastasia",
"koreasouth": "southeastasia",
"eastus2euap": "eastus"
},
"logAnalyticsLocation": "[variables('logAnalyticsLocationMap')[parameters('location')]]"
````

>**NOTE**: To find the available Azure regions for a Resource Provider, you can use the following PowerShell cmdlet:
>```Get-AzureRmResourceProvider -ProviderNamespace Microsoft.OperationalInsights | select -ExpandProperty Locations```

The domainNameLabel property for publicIPAddresses **must** be **unique**. domainNameLabel is required to be between 3 and 63 characters long and to follow the rules specified by this regular expression ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. As the uniqueString function will generate a string that is 13 characters long in the example below it is presumed that the dnsPrefixString prefix string has been checked to be no more than 50 characters long and to conform to those rules.

>**Note**: The recommended approach for creating a publicIPAddresses is to use the Microsoft.Network.PublicIpAddressCombo in createUIDefinition.json which will validate the input and make sure the domainNameLabel is available, however if a Managed Application creates new publicIPAddresses in a template without using this element to provide parameters then it should ensure that the domainNameLabel properties used for them are unique

````json
"parameters": {
"dnsPrefixString": {
"type": "string",
"maxLength": 50,
"metadata": {
"description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."
}
}
},
"variables": {
"dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]"
}
````

* For the public endpoints the user will interact with, you **must** provide this information in the **output** section in the templates, so it can be easily retrieved post deployment

````json
"outputs": {
"vmEndpoint": {
"type": "string",
"value": "[reference(concat(parameters('vmName'), 'IP')).dnsSettings.fqdn]"
}
}
````

* If using *nested templates*, ensure you are referencing the outputs from the nested templates into the *mainTemplate.json*

````json
"outputs": {
"vmEndpoint": {
"type": "string",
"value": "[reference('nestedDeployment').outputs.vmEndpoint.value]"
}
}
````

* To set the managed application resource name, you must use ````"applicationResourceName"```` in the ````createUiDefinition.json```` file. If not, the application will automatically get a GUID for this resource.
Example usage:

````json
"outputs": {
"vmName": "[steps('appSettings').vmName]",
"trialOrProduction": "[steps('appSettings').trialOrProd]",
"userName": "[steps('vmCredentials').adminUsername]",
"pwd": "[steps('vmCredentials').vmPwd.password]",
"applicationResourceName": "[steps('appSettings').vmName]"
}
````
Binary file added 1-contribution-guide/images/artifacts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 1-contribution-guide/images/downloadrepo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 1-contribution-guide/images/managedapps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 1-contribution-guide/images/structure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 1-contribution-guide/images/validation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading