Monday, April 11, 2016

Including Reference Assemblies in plugins

I recently had to reference the Newtonsoft.Json dll from within a CRM plugin and run into the infamous problem that there is no real support for referenced assemblies from custom plugins or workflow activities. This post provides a workaround using ILMerge.

The Problem


This has been a feature gap since plugins were introduced in CRM, you often want to reference external dll libraries from within your plugin. First, let’s look at how the CLR (.Net) loads referenced assemblies in order to understand the problem a little better. During runtime, what happens with referenced assemblies is that the CLR will try to load the referenced assemblies from some predetermined locations. For example, it will try to locate and load that assembly from the GAC or from the same directory as where the current process is executing. When you compile an assembly and it has other references, what happens is that the referenced assemblies get dropped in the same bin folder as your compiled assembly so they can be easily located and loaded at runtime.

That works great, and in CRM there is also the concept of the “bin” folder but the usage of it is a bit deprecated or not recommended (see ….). So in theory if you have access to the CRM server you could drop all your referenced assemblies in the “assembly\bin” folder or you can install your referenced assemblies in the server GAC and ten they will be able to be loaded at runtime. However, this is a big problem because you don’t always have access to the server and because depending on a specific server is risky as your servers might change, there could be a load balancer with multiple servers, etc.

So what else can you do if you have to register your plugin in the database? Well, when you register your plugin in the database what happens is that CRM will deserialize your dll content and load your plugin type explicitly, but you have no way of telling CRM that it must also load another assembly and you have no way to upload a reference assembly to the database. Certainly all .Net native assemblies like System.dll can be loaded because you can assume .Net to be available from all CRM servers, but what if your reference assembly is a third party like Newtonsoft.Json.dll ? In cloud environments (plugins in sandbox mode), reference assemblies can be dangerous because you do not know what code they are running in your shared cloud servers, so this probably explains why there is no support for reference assemblies in CRM. For plugin assemblies this risk is easily mitigated by running your plugin under partial trust in the CRM sandbox which uses code access security, .Net framework’s way of allowing external code to execute in a safe manner. This is why your plugins would fail to do things like try to read a local file or shut down the current server (you wouldn’t expect that to work in cloud environments!).


The Solution


So at this point you are left with 2 options: You can either compile the source code of your reference assemblies into your plugin assembly (if you have the source code) or you can ILMerge the reference assembly with your plugin assembly. In this example I will focus on the second option and I will illustrate exactly how I did it for the example of Newtonsoft.Json.dll in the following 3 simple steps:



1.        Add ILMerge Nuget to your plugins project

2.       Add Newtonsoft.Json Nuget package to your plugins project


3.       Now you simply need to edit your project configuration in Visual Studio such that when you build your plugin it automatically merges it with your reference assemblies (so you will never have to manually do ilmerge). To do this go to the “Build Events” tab of your project settings and under “Post Build event command line” box enter the following:

$(SolutionDir)packages\ilmerge.2.14.1208\tools\ILMerge.exe /keyfile:$(SolutionDir)/.snk /target:"library" /copyattrs /out:$(TargetDir)$(TargetName)$(TargetExt) $(ProjectDir)$(IntermediateOutputPath)$(TargetName)$(TargetExt) $(SolutionDir)packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll

Note you might need to modify the command above according to the version of the Nuget package you installed in previous step and you have to specify the location of your SNK file that you use to sign your plugin assembly.

Now when you build your plugin assembly, the Newtonsoft.Json.dll is embedded inside your plugin so CRM will not need to load the reference assembly. There you go, I hope you find this useful and simple enough.  

Monday, March 14, 2016

How to set EntityCollection output parameters in custom actions

One of the greatest things about custom actions is that they support defining input and output arguments of type EntityCollection. However, because the process designer does not support UI for consuming this type then we have to do it via code. This article explains some tips if you think that could be useful for you.

If you are familiar with custom actions introduced in CRM 2013, you might have noticed that they have input and out parameters. What is interesting is that a data type “EntityCollection” is supported which means your action can take as input a number of entities or it can produce a number of entities as the result (like RetrieveMultiple). The first thing you might wonder is why the heck would you want to use EntityCollection as output arguments, it if can’t even be consumed from the workflow designer. But if you are reading this post chances are you have a scenario in mind. In many cases you might want EntityCollection as input parameters, but is more unusual to need an output of EntityCollection. I can think of a few scenarios, and most recently I had to use this for encapsulating a set of business logic in a custom action which would then return a set of entities. This custom action might be consumed from external systems and makes it simple to implement all the business logic in a custom action so from the external clients it will be straight-forward to consume this action without having to call various SDK operations and implementing the logic at the client.

Once you have identified the scenario you need to keep in mind that the result (output) of your custom action will need to be consumed only from code (external client, JavaScript, plugins, etc.) because unfortunately the CRM native process designer is still incapable of understanding entity collections. Now, how can you set an output parameter in your custom action that is type of EntityCollection if you cannot do that via the process designer?

My first instinct was to implement a custom workflow activity and then insert it in the action definition as a custom process step:






























Inside the custom workflow activity, you have full access to the IExecutionContext, including the InputParameters and OutputParameters collections. Therefore, I assumed I you could set your EntityCollection output parameter via code as seen below:


While technically this compiles and executes fine, I was surprised to see that when calling my action, the output parameter was blank, even though I was setting the value from the custom workflow activity. I imagine this might be due to the fact that output parameters are only set after the main pipeline operation and perhaps the custom workflow activity is executing a little bit before that thus all output parameters get wiped after the main operation but before the value is returned to the client.

Therefore, I had to change my approach. I implemented the exact same code, but this time I used a plugin registered on the PostOperation of my custom action, this way I can make sure that the main operation has already passed and whatever I store in the output parameters collection will be returned to the calling client. This finally worked!


So the lesson here is that setting output parameters (in general) must be done in the PostOperation part of the pipeline, therefore it can only be done via plugins!

Keep in mind that setting input parameters as EntityCollection is more trivial because it is up to the calling client to pass those parameters, and in this case, although you cannot consume those input parameters inside the action process designer, you will be able to access them from either a custom workflow activity inside your action or from plugins. I tend to prefer custom workflow activities because this way your entire logic is defined inside the action itself and there is no additional logic running in plugins, but it depends on the scenario and complexity too.


Monday, January 11, 2016

OptionSet vs Lookup for implementing lists in CRM

In most CRM implementations we experience the dilemma of custom entity vs. OptionSet for implementing lists. This post seeks to point some of the considerations to keep in mind when making this decision.

Imagine you want to capture the "Industry" of your leads/accounts as this information might be valuable for reporting and BI. Every organization has different definitions of "industries" because there is no global standard list of industries that is useful for everyone. So you decide to create and maintain your own list of industries. Now the problem becomes: Should you implement this list as an "Industry" entity or should you simply create an OptionSet with the list of industries?
As everything in the technology consulting industry (pun intended), the answer is always: It depends! There is no exact formula of science to solve this dilemma but I've had numerous discussions with colleagues and customers in this respect and I thought of gathering some guidance that might help you decide:
 
1. How often does this list change and who maintains it?
If your list of industries is changing often or if you expect business users to contribute by maintaining this list, it is recommended you implement as a custom entity rather than option set. The reason is that the custom entity adds richer flexibility to create, update or remove values without having to involve IT. You can easily control who can edit the list by leveraging the security roles on the custom entity. However, if your list rarely changes (e.g. list of countries) and it needs to go through IT then you should probably use Option Set.

2. Do you need to support multiple languages?
For us in Canada we usually always implement CRM in both English and French. If your industry list is defined as an OptionSet you can support languages much easier because it is just a matter of translating labels so that each user will always see the list in their preferred language. However, if you use a custom entity, the list is data (instead of metadata) and data does not have the notion of language. Things get complicated here. The typical solution is to use a concatenated primary fields in which a workflow automatically appends English and French labels together with a separator. For example you have an industry record called "Travel / Voyage". But this gets too complex if you have more than 2 languages and creates unnecessary long labels. Not to mention language laws dictating which language should appear first can cause a headache. For this aspect, the winner is by far Option Sets.

3. Do you need to capture additional fields?
Imagine in our example, you also need to capture an industry code and size along with the industry name. It would be almost impossible to achieve this with Option Sets so you would definitely need to implement your industry list as a custom entity. Even if today you only need the name, consider whether it is likely that in the future you have to capture additional attributes and if so, you should favor using a custom entity over Option Sets.
4. Environment transport and synchronization
The nice thing about option sets is that when you transport a solution you are also transporting all the labels and values to your target environment and you are sure that the list is consistent in your dev/test/prod environments so you can rely on specific values existing in the list. However, if you implement as an entity, you will never know who will create, update or delete values from one environment and not the other. So you will end up with different value in each environment. Furthermore, you might end up with equal values but different Ids. For example, you might have industry "automobile" in dev with a specific GUID but the same industry in production with a different GUID. This takes me to the next point about:

5. Workflows and reports/views
You might want to do industry specific reports or workflows and include logic such as "if this customer is in the banking industry then do X". Using OptionSets this is safe because the value "Banking Industry" is consistent across all environments so you can add such condition to your workflow. However, if you use a custom entity, you cannot rely on values having the same GUID in all environments so you cannot define such logic safely. The workaround would be that in your workflow/view/report you say "if industry.name contains 'banking' then do X". This works in most cases but is not completely safe; for example, somebody might have renamed "banking" to "finance" and suddenly your workflow is broken. The safest is to use an OptionSet which you are sure will exist for a specific value. If you rely on reports and workflows such as the one described above you might be better off using Option Sets.

6. Dependent lists
Consider whether your list will have another dependent list. For example list of states/provinces depends on the value selected from the list of countries. You can achieve dependent lists as both OptionSets and custom entities. The only difference is that for custom entities it is easier because you don't need to write any code, simply configure the form to show only states/provinces related to the country selected (assuming there is a relationship between state/province and country). I think this is the least important factor but is a small advantage of custom entities as it is easier to filter the list based on another related value. If you define your list as a custom entity you can even do advanced filtering such as displaying only industries which exist in the country of the current lead (assuming N:N relationship between country and industry). That can be much harder to do via OptionSet (custom development) while it is just a matter of configuring the form in the case of custom entity.


I usually go in the order above to make a decision as the first items have more impact than the last items of the list above. I hope this can help you assess the best solution for your situation, let me know if you have other considerations I missed!

Wednesday, October 14, 2015

Comunidad CRM y la Mesa de Expertos – Otoño 2016

Announcing the Expert Table for Fall 2016 for my Spanish readers, don’t miss out this event!

Come lo ha venido hacienda la Comunidad CRM, estará presentando las novedades de CRM 2016 por medio de una mesa redonda con la participación de varios MVP de habla hispana . Desafortunadamente no podré asistir a este evento puesto que estaré de viaje. Sin embargo, no se pierdan esta increíble oportunidad de aprender sobre las novedades de la próxima versión de CRM y sobre todo la oportunidad de hacerle preguntas a nuestros expertos en vivo. Registrate aqui! Este es el extracto de introducción a la próxima mesa:

Si, leíste bien. CRM 2016. Ya se asoma una nueva versión que estará disponible tanto en CRM Online como On-premises y cargada, muy cargada de novedades por demás interesantes.

Es por ello que los expertos más destacados de habla hispana en Dynamics CRM se vuelven a reunir para compartir las novedades de esta nueva versión, entre otras:

  • La nueva experiencia de servicio – el Interactive Service Hub
  • La nueva versión de la Base de Conocimiento
  • Power BI para Servicio
  • La nueva app para Outlook
  • La nueva búsqueda
  • Trabajo desconectado (“offline”) y novedades en las apps móvliles
  • Plantillas para integración con Excel y Word
  • OneDrive
  • Novedades de la plataforma
  • Social CRM

Y hay muchas más novedades! Inscríbete y compártenos que opinas de CRM 2016. Recuerda utilizar #mesa2016.

Aprovecho también para felicitar a los líderes de la comunidad de todo su esfuerzo para compartir contenido y crear conocimiento a nivel mundial sobre CRM en español. También los invito a navegar el sitio para ver la cantidad de recursos y cursos a su disposición.

Tuesday, October 13, 2015

Don’t forget your case title and customer

Case is a special entity in CRM because it has many out-of-the-box special logic.  Sometimes this can be problematic as it forces us to use some fields we might not need.

I’ve always found many customer scenarios in which the “Customer” field adds no value to the case and we would like to remove it. Although less often, you might have found a scenario in which the “Title” field of the case is also not needed. The bad news is that CRM forces you to use those 2 fields in the case, otherwise you might encounter some issues.

For the “Customer” field you can get around it but you need a plugin which is going to set your customer to a dummy hard-coded customer on the Pre-Validate operation whenever a case is created. I haven’t seen this work with sync workflows or business rules (although I haven’t investigated much), unfortunately seems like a plugin might be required for this. Once you have this plugin you can simply hide the Customer field from the form, make it read only and remove this field from all the views. Then your Customer field will be used but not really used. Note that in order to hide this field from the form you might want to make it read-only and then move it to a new "section and hide the entire section. This will help you keep things clean on your form by moving all the “unused” but “locked” fields in a hidden form section.

Regarding the title field, CRM will not prevent you from not using this field. You can also hide it an make it read-only and things will seem to work fine. However, as soon as you start using SLA’s you will run into this problem:

Workflow '{F5245D54-9BA6-4E4B-AB86-9131A076FB4D}' failed due to error: Unhandled Exception: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
   at System.Activities.WorkflowInvoker.Invoke(Activity workflow, IDictionary`2 inputs, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
   at Microsoft.Crm.Workflow.SynchronousRuntime.SynchronousWorkflowActivityHost.ExecuteWorkflowUsingInvoker(Activity workflow, ICommonWorkflowContext context)
   at Microsoft.Crm.Workflow.SynchronousRuntime.SynchronousWorkflowActivityHost.StartWorkflow(WorkflowActivationData activationData, ICommonWorkflowContext context)

As you might know, SLA works as workflows behind the scenes. As soon as you create SLA’s there are some background processes (workflows) created which represent the SLA you have created. Some of these workflows are synchronous and it turns out that if your case has no title, the workflow fails with the above error message preventing the creation of the case. This can be easily fixed by either using the case title or placing some dummy value in it. In our case we simply copied the ticket number into the case title. However, one must admit that it is difficult to arrive to such conclusion from the error message above, that is why I’m sharing this finding, I hope you find it useful!

Monday, September 14, 2015

CRM 2016 announced! My favorite features to look out for

 

You might have seen the press release (http://news.microsoft.com/2015/09/08/microsoft-reinvents-productivity-with-upcoming-release-of-customer-engagement-solution/), CRM 2016 is no longer under NDA and will be released by Q4 of this calendar year! Below is a very quick summary of favorite features I have extracted very high-level (in bold are my biased favorite features!) but if you’d like to read more about it, I suggest you review the release preview guide: http://download.microsoft.com/download/D/5/D/D5D38A09-6A5C-4DC0-8649-3A4F39A8F8F3/Microsoft_Dynamics_CRM_2016_Release_Preview_Guide.pdf

 

 

MOBILE


1.    Full offline support to create, update and delete records while offline. *
2.    Open SharePoint/OneDrive documents from CRM mobile app.
3.    App-to-app deep linking
4.    New UI controls and ability to bind data fields to UI controls
5.    Task bases experiences: Show relevant data from multiple records in a single screen for a given task*
6.    Preview phone/tablet experience from browser while designing forms.
7.    Full web resource (IFRAME) support in mobile.
8.    Integration with Intune for secure CRM data with Mobile Application Management (MAM) in BYOD scenarios.

 

CRM ONLINE*
1.    Data encryption for CRM server
2.    New data centers in Canada (Toronto and Quebec City) and India
3.    Bulk Data Loader tool

 

PLATFORM
1.    Enhanced modern API: REST, OAuth 2, JSON, OData v4.
2.    Next Generation Search: Multi-entity search with relevance ranking*
3.    Azure Machine Learning: Easily configure ML integration for product cross sell recommendations*

 

SALES / SERVICE / MARKETING
1.    CRM app for Oultook (PC / Mac / any browser) *
2.    Excel integration including mobile/tablets and Excel templates for viewing sales data
3.    Consolidated document storage integration from SharePoint, OneDrive and O365 groups.
4.    Document Generation: in one click generate Word/Excel documents from CRM data (orders, invoices, etc.)
5.    Cortana integration*
6.    Single- and Multi-stream service hubs dashboards
7.    Re-designed forms for cases, accounts, contacts and activities with reduced clicks, wall filtering, quick actions on related records.
8.    External Party Access: Give access to your CRM data to third party (customers, partners, etc.)
9.    Enhanced knowledge management curation process.
10.    CRM surveys sent to external people (email/web). Results and analysis captured in CRM. (requires Azure to host feedback page)
11.    Field Service Capabilities (FieldOne acquisition)

 

MDM*
1.    Enabled SMS channel for marketing campaigns (inbound/outbound) in MDM
2.    HTML email rich editor in MDM

 

USD
1.    Centralized auditing configuration
2.    OOB integration with Azure 3rd party systems like HDInsights
3.    Stability and Performance enhancements
4.    Simplified install & upgrade experience. Custom DLLs distributed through CRM server configuration.
5.    PowerBI dashboard

 

MSE*
1.    Feeds from custom sources (RSS) and non-public sources (Yammer)
2.    “Intelligent Social”: Target accounts and share content, detect potential leads vs. cases
3.    Improved sentiment analysis by domain-specific models.
4.    Groups and custom roles
5.    Social Center: Post to Facebook/Twitter with rich multimedia content from social center.

* Only available in CRM Online.

Monday, August 24, 2015

Agile CRM development with SCRUM

I recently worked in an agile CRM project as the scrum master and was able to learn some good tips of using scrum for CRM development.

I am of the belief that the waterfall days are coming to an end, mostly due to its unsustainable release cadence, inefficiency when reacting to the 'unknown' and the large amount of waste that goes towards tight controls and project management as opposed to focusing effort on product quality and continuous business value generation. In the world of CRM implementations this becomes even more evident because of various factors such as the ability of the platform to quickly produce business value and adapt in an iterative manner, even when the final outcome is yet to be discovered. CRM can be configured very quickly which allows you to achieve valuable work (increment) in iterations (sprints) that can be as short as 1-2 weeks. The fact that you can have stakeholders provide early feedback continuously (sprint reviews) allows you to adapt very quickly to changing demands and gives your users a chance to get familiar with CRM early on. Continuous feedback leads to more valuable user feedback because users have something tangible to review instead of having to imagine what everything will look like. If you are reading this you probably already understand the value of agile and I don't need to convince you further. Now let's look at the typical challenges we find with agile frameworks like scrum and some ideas from my experience that can make your life easier.

1. Your customer needs to fund the project and to do so they need the cost, scope and schedule upfront. This has been the hardest challenge, specially in the consulting world as organizations are used to think that to manage risk means to transfer to someone else (you) the risk of changes in scope, cost and schedule. This is an antiquated mentality when it comes to complex software development because you cannot plan for everything in advance and expect that the requirements you document today is exactly what you are going to need. The result is typically that consulting companies add a large amount of contingency and charge you more for any change in your original requirements (change requests). The end result is that your customer ends up paying more and not getting the optimal solution. What is worse, is that they will not know that the solution is not really doing what they need until it is too late, too much has been wasted and the budget cannot be increased. This is by far the main reason I see waterfall projects fail. But what can you do about it if your customer's culture is waterfall and they want a fixed-everything upfront before they can "fund the project"? I think the magic word here is 'trust'. The best you can do (other than finding another customer that understands that we are not in the 90s) is to earn their trust. Certainly this does not happen overnight but if you are able to build this trust you might eventually be able to propose 'giving it a try' and educating your customer on modern software development practices. The good thing about agile is that you see the results very quickly and you can start by funding a single sprint to see how things go (the bad part is that the first sprint is always the hardest!). One important tip is to make sure your customer trusts you enough to not think that you are just trying to make more money with them, this will not go well and is very far from your objective. In reality your objective is to save them money and increase their probability of success, they need to see that intention clearly. Regarding funding, you can help them switch from the 'fund a project' mentality to the mentality of 'fund a team that is going to give you optimal business value for your project(s)'.

2. You are not sure how to manage the CRM development and test environments for an agile project. This is one where you might have to try a few things and see what works best with your development team. My suggestion is to start with something as simple as possible and empower your development team to decide if they want to make changes to this during sprint retrospectives. The simplest is to have one (yes, one!) shared environment (CRM organization/tenant) for development and test. I have blogged in the past here about how to manage multiple dev and test CRM environments and some good practices about that, but I invalidate my own post when it comes to agile. You want to reduce waste and not have to spend time migrating code, merging solutions and fixing environment synchronization issues. This is why you should at least try to have everyone working on the same environment. You will certainly need some rules such as one developer cannot block the environment for debugging while everybody else needs it; but this is why the daily scrum exists. Make sure you have a daily scrum and that it is actually a 15 min maximum daily scrum and not some status report or defect logging meeting, do not invite anybody outside of your development team to the scrum meeting, this time should be wisely used so developers can synchronize and coordinate activities to be the most efficient. Developers can always have their own sandbox environments but these are not development environments as you should not promote code from sandbox to development.

Regarding test environment I initially had a separate test environment but the development team quickly realized that it was causing too much overhead with very little value. Instead, try to get everyone to test during the sprint (add testing to your definition of done). A very hard thing to do is to bring acceptance testing as part of the sprint and not an ad-hoc activity after the sprint. Get your product owner engaged to do the necessary acceptance testing prior to sprint review, and even consider incorporating UAT as part of your sprint. This is not easy but will give you increased agility and faster release cycles. If you succeed bringing acceptance testing as part of your sprint then it is more clear why you would not need a separate test environment.

3. You don't know how long your sprints should be and how much PBIs you should forecast for a given sprint. I think this is one of the places where CRM has an advantage over custom development, you can do a lot in very little time. Therefore, I would suggest to start with shorter sprints (maybe 2 weeks is a good start). Never do a sprint over 4 weeks or you might end up just doing waterfall! At first you will most likely underestimate and not complete all the PBIs by the end of the first sprint. This is not ideal but is acceptable as long as you don't "extend" the sprint (sprints are time boxed, never extend the end date of a sprint, no matter what). The reality is that at first you might struggle with sprint planning, this is normal, try to forecast how much you can complete in your first sprint by keeping in mind your definition of done (make sure you have one!). So think about how much time it will take you not just to code/configure but also to design, analyze, unit test, document, etc.) each PBI. Additionally you need to work with the product owner to select the most urgent PBIs while keeping a balance for the skills required to deliver the sprint. For example, if you have a dev team of 6 but only 1 person knows SSRS, then you cannot realistically include only SSRS reports in the sprint, even if those reports are the most urgent PBIs. You need to make sure your team skill set is proportionate to the skill set required to deliver the sprint otherwise you might end up with 1-2 very busy individuals while others have a hard time finding how to contribute. Additionally when you forecast your sprint make sure you reserve a 10% of total sprint time to do backlog refinement (most teams fail to do this). There are multiple estimation techniques such as planning poker, however, when forecasting your sprint always ask your team at the end to do a 'gut check' (are we confident to be able to deliver these PBIs within next sprint?). I have found gut checks to be very useful and accurate, everyone must keep in mind the time spent in meetings, backlog refinement, sprint reviews and retrospectives, etc. because all these activities are also part of your sprint, not just the development activities. So in reality you spend only about 80% of your sprint capacity developing PBIs (note that development includes design, code, unit test, etc). One more thing about sprints, try to keep the same duration of sprints and the same start and end day of the week. Eliminate any time between sprints (yes this can be hard). Sprint n+1 should start the day after sprint n finishes, this will give you greater agility, as opposed to having "ventilation" time between sprints to do activities that should actually have been done during the sprint.

4. You are uncertain about how you can incorporate UAT and deployment into the scrum process. This is one of those places where reality sometimes crashes with scrum. If you can get your customer to perform UAT during the sprint and you make that work then you are probably a scrum super ninja that is not learning anything new from this post. So that's the ideal scenario, but we know for various reasons this does not always work. In this case you will need to do as much acceptance testing with the product owner during the sprint as possible and then release to UAT as part of your definition of done. The problem is that your team will probably get interruptions for UAT support as the UAT testers are usually in a completely different cycle as your sprint cycles. You will have to deal with this and account for this during sprint planning, but again the more you can test earlier the better because you will get less UAT defects and distractions. In this case you might need a separate environment for UAT and you would need to forecast in your sprint planning the activities for UAT release. Regarding deployment to production, I have often heard the misunderstanding that in scrum you are supposed to deploy to production at the end of every sprint, that's not correct. You can release to production as often as you want, from multiple times per sprint to once very number of sprints. However, at the end of each sprint, your work should be "potentially releasable" according to the scrum guide, so you shouldn't have broken critical functionality at the end of the sprint, even if you don't plan to release to production. It is a good idea to release as often as you can, try to incorporate the DevOps approach and bring development and operations together as much as possible, this will help you achieve a faster release cycle and a smooth transition to production. Of course this is not something that you will get right from one day to the next, DevOps requires multiple changes and great amount of practice and experience to become efficient (beyond the scope of this post).

 

Scrum is an empirical process, so at its core it has transparency, inspection and adaptation. Make sure that you pay attention to these 3 values during your various events, the key is not how to successfully setup a scrum project but more about your agility to inspect and adapt your process to produce business value faster and reducing waste, that is your success criteria! There are certainly many other challenges and suggestions, I might blog more about this in the future, but I would conclude with one famous quote from scrum that couldn't be more accurate: scrum is a framework that is easy to understand but very hard to master.