[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: preventing commits on branches
From: |
Don J. Norton |
Subject: |
RE: preventing commits on branches |
Date: |
Fri, 2 May 2003 09:28:43 -0700 |
|-----Original Message-----
|From: address@hidden [mailto:address@hidden
|Sent: Friday, May 02, 2003 5:26 AM
|To: address@hidden
|Subject: preventing commits on branches
|
|
|Does anyone have any example scripts (preferably perl) which can be
|activated via the commitinfo hook and which can prevent
|commits to specific
|branches / by specific people / a combination of both. If no scripts
|available, any advice on this topic would be appreciated.
|
|Jason Gibbons
Hi Jason,
I had a similar need, and with the help of a generous person on
this list, was able to develop just such a beast. It isn't
written in perl (shell script), and it is somewhat rudimentary,
but it may serve your needs anyway.
I believe it would be quite useful if this model, or one similar
to it, were built-in to the cvs distribution.
The precommit_check utility uses three control files to...
1) Not ever allow check-ins from specific users
(I use this to prevent check-ins from anonymous
internal accounts).
2) Specify a list of people who are allowed to check
in changes to a specific branch or the HEAD.
3) Specify a list of branches to lock completely
(this is useful as a "breaker" switch, to
temporarily turn on/off access all the "approved"
people without having to reconstruct list #2
each time).
Finally, the precommit_check script itself uses all three
control files to perform commit-time validation and prevents
check-in if all the necessary criteria are not met.
What I have not done in this is leverage module definitions
in any way. If anyone finds this useful enough to do so, I
would appreciate a return of the improvements.
Hope you find this useful.
-Don Norton
PS: The "PS" prefixes are an abbreviation of my company
name (PolyServe). I'm sure you'll want to remove/modify
those.
======================================== cut here ===========================
# ================= PS_restricted_accounts
#
# List all accounts which are prohibited from performing commit operations
#
build
qa
======================================== cut here ===========================
# ================= PS_branch_access
#
# The format of this file is as follows:
#
# branchname: user1 user1
#
# For an entry to be effective, the first character must be the beginning
# of the branch name. Everything following the colon should be a
# space-separated list of valid users. All users authorized to change
# the branch in question must be on one line. The absence of a branch
# name here results in no per-user restrictions.
#
# Comment lines should start with '#' for consistency and namespace
# protection from cvs branch tag names.
#
project_HEAD: joe bob frank
project-branch1: mike tim nancy cheryl
======================================== cut here ===========================
# ================= PS_branch_locks
#
# This file should include a list of all branches in which commit
# operations are currently restricted. Commenting out (prefixing
# with a "#" removes the branch lock.
#
# Artificial branch names consisting of the top-level CVS directory
# appended with "_HEAD" are supported.
# For example, /CVS/klondike maps to a branch name of klondike_HEAD.
#
#project-branch1
project_HEAD
======================================== cut here ===========================
#!/bin/bash
#
# Exits non-zero if the requested check-in shouldn't be allowed,
# for whatever reasons deemed appropriate by this script.
#
# Checks for the following are currently implemented:
#
# Invalid anonymous id
# Branches being locked
# Valid developer on a per-branch basis
CVSSUPPORT=`dirname $0`
RESTRICTED=${CVSSUPPORT}/PS_restricted_accounts
BRANCHACCESS=${CVSSUPPORT}/PS_branch_access
BRANCHLOCKS=${CVSSUPPORT}/PS_branch_locks
# List of people to bug if the check-in fails
bug_people="cvsadmin"
# List of branches for which check-ins are not currently allowed
locked_branches=`cat ${BRANCHLOCKS} | grep -v "^#"`
control_file_check()
{
if [[ ! -f ${BRANCHACCESS} ]]; then
echo Fatal error: ${BRANCHACCESS} file not found
echo Contact ${bug_people} for assistance
exit 1
fi
}
no_anonymous_id ()
{
# Confirm the user is not one of the various anonymous accounts
# to help ensure tracability of the change being made.
account="$(id -un)"
grep -n "^${account}" ${RESTRICTED}
if [[ $? -eq 0 ]]; then
# Account name found in restricted list
echo " "
echo " ********** Warning ********** "
echo " ******* Commit Failed ******* "
echo " "
echo "CVS commit not allowed by anonymous account $account"
echo " "
echo " ******* Commit Failed ******* "
echo " ********** Warning ********** "
echo " "
return 1
fi
return 0
}
validate_user_on_branch()
{
local branch=$1
# Confirm this user is allowed to make changes to this branch
account="$(id -un)"
grep -n "^${branch}" ${BRANCHACCESS}
if [[ $? -eq 1 ]]; then
# No controlled branch found
echo Branch \"${branch}\" is not under per-user access control
return 0
fi
userlist=`grep "^${branch}" ${BRANCHACCESS} | sed 's/^.*://'`
for user in ${userlist}
do
if [[ ${account} = ${user} ]]; then
echo User \"${account}\" authorized to modify branch
\"${branch}\"
return 0
fi
done
# Valid user not found - return error
echo User \"${account}\" is not authorized to modify branch
\"${branch}\"
return 1
}
validate_branch ()
{
# Process each file to be checked into cvs
for file in $@
do
# Get branch info from CVS/Entries file
#
# Note for the faint of heart: the relevant lines in the
# CVS/Entries file are transferred from the user's working
# repository to the server where this script is executed
# during a commit. This allows the following action to
# succeed.
branch=`grep "^/${file}/" CVS/Entries | awk -F/ '{print $NF}' |
cut -c2-`
if [[ ${branch} = "" ]]; then
branch=HEAD
repository=`cat CVS/Repository | awk -F/ '{print $3}'`
branch=${repository}_HEAD
echo file \"${file}\" is implicitly on ${branch}
else
echo file \"${file}\" is on branch \"${branch}\"
fi
validate_user_on_branch ${branch} || exit 1
for br in ${locked_branches}
do
if [[ ${branch} = $br ]]; then
# Branch locked - notify user and return failure
echo " "
echo " ********** Warning ********** "
echo " ******* Commit Failed ******* "
echo " "
echo "Branch ${branch} is closed for commits "
echo "Please contact one of the following
before proceeding: ${bug_people}"
echo " "
echo " ******* Commit Failed ******* "
echo " ********** Warning ********** "
return 1
fi
done
done
# No matching locked branches - return success
return 0
}
#
#===============================================================================
#
#echo $0 args: \"address@hidden"
# Confirm control files exist
control_file_check
# Confirm user is not an anonmous id
no_anonymous_id || exit 1
# Shift off directory name (first argument), leaving only file names to process
shift
# Confirm the target branch is not locked
validate_branch $@ || exit 1
exit 0