Custom Check in policy in TFS?

廉价感情. 提交于 2019-11-30 16:22:37

It's not appropriate to raise UI in a custom check-in policy - the lifecycle of a check-in policy is very short, and they will be evaluated frequently and not necessarily in a UI context or on the UI thread.

Can you determine programmatically whether the appropriate XML files are being checked in? If so, you could create a custom check-in policy that fails if the XML files are not pended for add.

Gated Check-in may be the best solution to this problem: does the build fail if these XML files do not exist - or would unit tests fail if these files are missing? If so, this is a perfect candidate for Gated Check-in, which will prevent these check-ins from occurring.

I would create a custom build template that checks for these xml files. Make it a gated check-in and you've got your solution.

The Evaluate method is supposed to be quick and should not show UI, but there is an event on the policy that triggers when the user interacts with the policy called Activate, this is a good moment to show UI and communicate with the policy. You could do something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JesseHouwing.CheckinPolicies
{
    using System.Windows.Forms;

    using Microsoft.TeamFoundation.Client.Reporting;
    using Microsoft.TeamFoundation.VersionControl.Client;

    [Serializable]
    public class ConfirmPolicy :PolicyBase
    {
        private AffectedTeamProjectsEventHandler _affectedTeamProjectsEventHandler;
        private EventHandler _checkedPendingChangesEventHandler;

        public ConfirmPolicy()
        {
        }

        public void StatusChanged()
        {
            _userconfirmed = false;
            OnPolicyStateChanged(Evaluate());
        }

        public override void Initialize(IPendingCheckin pendingCheckin)
        {
            _affectedTeamProjectsEventHandler = (sender, e) => StatusChanged();
            _checkedPendingChangesEventHandler = (sender, e) => StatusChanged();

            base.Initialize(pendingCheckin);
            _userconfirmed = false;                
            pendingCheckin.PendingChanges.AffectedTeamProjectsChanged += _affectedTeamProjectsEventHandler;
            pendingCheckin.PendingChanges.CheckedPendingChangesChanged += _checkedPendingChangesEventHandler;
        }

        protected override void OnPolicyStateChanged(PolicyFailure[] failures)
        {
            _userconfirmed = false;
            base.OnPolicyStateChanged(Evaluate());
        }

        public override void Activate(PolicyFailure failure)
        {
            if (MessageBox.Show("Confirm the policy?", "Policy Check", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                _userconfirmed = true;
                base.OnPolicyStateChanged(Evaluate());
            }
        }

        public override PolicyFailure[] Evaluate()
        {
            if (_userconfirmed == true)
            {
                return new PolicyFailure[0];
            }
            else
            {
                return new PolicyFailure[]{new PolicyFailure("User must confirm", this)};
            }
        }

        public override string Description
        {
            get { throw new NotImplementedException(); }
        }

        public override bool Edit(IPolicyEditArgs policyEditArgs)
        {
            return true;
        }

        public override string Type
        {
            get
            {
                return "User Confirm";
            }
        }

        public override string TypeDescription
        {
            get
            {
                return "User Confirm";
            }
        }

        public override void Dispose()
        {
            this.PendingCheckin.PendingChanges.AffectedTeamProjectsChanged -= _affectedTeamProjectsEventHandler;
            this.PendingCheckin.PendingChanges.CheckedPendingChangesChanged -= _checkedPendingChangesEventHandler;

            base.Dispose();
        }
    }
}

I haven't tested this exact code yet, it might need some tweaking, but this is the general thing to do. Right now it triggers on a change in the files being checked in, but you can subscribe to any of the other events as well (work item changes) or trigger your own evaluation of the project each time Evaluate is called.

Or you can just trigger the confirm once per checkin cycle. it's all up to you. You could even do a "Click to Dismiss" and skip the Messagebox altogether. Just set _userConfirmed=true and fire the PolicyStateChanged event.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!