Fix stale tag considerations
This commit is contained in:
@@ -16,6 +16,7 @@ jobs:
|
|||||||
- name: Sync tools checkout to tag
|
- name: Sync tools checkout to tag
|
||||||
env:
|
env:
|
||||||
TAG_NAME: ${{ github.ref_name }}
|
TAG_NAME: ${{ github.ref_name }}
|
||||||
|
EVENT_SHA: ${{ github.sha }}
|
||||||
GITEA_SERVER_URL: ${{ github.server_url }}
|
GITEA_SERVER_URL: ${{ github.server_url }}
|
||||||
GITEA_REPO: ${{ github.repository }}
|
GITEA_REPO: ${{ github.repository }}
|
||||||
run: |
|
run: |
|
||||||
@@ -34,18 +35,27 @@ jobs:
|
|||||||
cd "${CHECKOUT_PATH}"
|
cd "${CHECKOUT_PATH}"
|
||||||
git remote set-url origin "${SOW_TOOLS_REPO_URL}"
|
git remote set-url origin "${SOW_TOOLS_REPO_URL}"
|
||||||
echo "Fetching tools refs from ${SOW_TOOLS_REPO_URL}"
|
echo "Fetching tools refs from ${SOW_TOOLS_REPO_URL}"
|
||||||
timeout 120 git fetch origin --prune --tags
|
timeout 120 git fetch origin --prune --force --tags
|
||||||
|
TAG_SHA="$(git rev-list -n1 "refs/tags/${TAG_NAME}")"
|
||||||
|
if [[ -n "${EVENT_SHA}" && "${TAG_SHA}" != "${EVENT_SHA}" ]]; then
|
||||||
|
echo "Fetched tag ${TAG_NAME} resolves to ${TAG_SHA}, but the workflow event SHA is ${EVENT_SHA}."
|
||||||
|
echo "Refusing to build a release from a stale or mismatched local tag."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
git reset --hard "refs/tags/${TAG_NAME}"
|
git reset --hard "refs/tags/${TAG_NAME}"
|
||||||
git clean -fd
|
git clean -ffdx
|
||||||
|
echo "Release ${TAG_NAME} will build commit $(git rev-parse HEAD)"
|
||||||
|
|
||||||
- name: Build sow-toolkit binaries
|
- name: Build sow-toolkit binaries
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}"
|
CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}"
|
||||||
cd "${CHECKOUT_PATH}"
|
cd "${CHECKOUT_PATH}"
|
||||||
|
rm -f ./tools/sow-toolkit ./tools/sow-toolkit.exe
|
||||||
mkdir -p tools .cache/go-build
|
mkdir -p tools .cache/go-build
|
||||||
GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit ./cmd/nwn-tool
|
GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit ./cmd/nwn-tool
|
||||||
GOOS=windows GOARCH=amd64 GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit.exe ./cmd/nwn-tool
|
GOOS=windows GOARCH=amd64 GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit.exe ./cmd/nwn-tool
|
||||||
|
go version -m ./tools/sow-toolkit
|
||||||
|
|
||||||
- name: Pack release bundles
|
- name: Pack release bundles
|
||||||
id: pack
|
id: pack
|
||||||
|
|||||||
+23
-12
@@ -1396,8 +1396,10 @@ func newFeatGeneratedContext(dataset nativeDataset, lockData map[string]int) (*f
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for key := range retiredFeatKeys {
|
for key, retiredID := range retiredFeatKeys {
|
||||||
delete(lockCopy, key)
|
if lockedID, ok := lockCopy[key]; ok && lockedID == retiredID {
|
||||||
|
delete(lockCopy, key)
|
||||||
|
}
|
||||||
delete(existingFeat, key)
|
delete(existingFeat, key)
|
||||||
}
|
}
|
||||||
return &featGeneratedContext{
|
return &featGeneratedContext{
|
||||||
@@ -1466,7 +1468,7 @@ func (c *featGeneratedContext) featKeyExists(key string) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectRetiredFeatKeys(featDir string) (map[string]struct{}, error) {
|
func collectRetiredFeatKeys(featDir string) (map[string]int, error) {
|
||||||
baseObj, err := loadJSONObject(filepath.Join(featDir, "base.json"))
|
baseObj, err := loadJSONObject(filepath.Join(featDir, "base.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1501,7 +1503,7 @@ func collectRetiredFeatKeys(featDir string) (map[string]struct{}, error) {
|
|||||||
nextID = nextAvailableID(usedIDs)
|
nextID = nextAvailableID(usedIDs)
|
||||||
return rowID
|
return rowID
|
||||||
}
|
}
|
||||||
retired := map[string]struct{}{}
|
retired := map[string]int{}
|
||||||
modulePaths, err := collectModulePaths(filepath.Join(featDir, "modules"))
|
modulePaths, err := collectModulePaths(filepath.Join(featDir, "modules"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1567,7 +1569,7 @@ func collectRetiredFeatKeys(featDir string) (map[string]struct{}, error) {
|
|||||||
currentKey := rowIDToKey[rowID]
|
currentKey := rowIDToKey[rowID]
|
||||||
if overrideRequestsNullRow(override) {
|
if overrideRequestsNullRow(override) {
|
||||||
if currentKey != "" {
|
if currentKey != "" {
|
||||||
retired[currentKey] = struct{}{}
|
retired[currentKey] = rowID
|
||||||
delete(rowKeyToID, currentKey)
|
delete(rowKeyToID, currentKey)
|
||||||
delete(rowIDToKey, rowID)
|
delete(rowIDToKey, rowID)
|
||||||
}
|
}
|
||||||
@@ -1576,7 +1578,7 @@ func collectRetiredFeatKeys(featDir string) (map[string]struct{}, error) {
|
|||||||
if rawKey, present := override["key"]; present {
|
if rawKey, present := override["key"]; present {
|
||||||
if rawKey == nil {
|
if rawKey == nil {
|
||||||
if currentKey != "" {
|
if currentKey != "" {
|
||||||
retired[currentKey] = struct{}{}
|
retired[currentKey] = rowID
|
||||||
delete(rowKeyToID, currentKey)
|
delete(rowKeyToID, currentKey)
|
||||||
delete(rowIDToKey, rowID)
|
delete(rowIDToKey, rowID)
|
||||||
}
|
}
|
||||||
@@ -1585,14 +1587,14 @@ func collectRetiredFeatKeys(featDir string) (map[string]struct{}, error) {
|
|||||||
newKey, ok := rawKey.(string)
|
newKey, ok := rawKey.(string)
|
||||||
if !ok || newKey == "" || strings.TrimSpace(newKey) == nullValue {
|
if !ok || newKey == "" || strings.TrimSpace(newKey) == nullValue {
|
||||||
if currentKey != "" {
|
if currentKey != "" {
|
||||||
retired[currentKey] = struct{}{}
|
retired[currentKey] = rowID
|
||||||
delete(rowKeyToID, currentKey)
|
delete(rowKeyToID, currentKey)
|
||||||
delete(rowIDToKey, rowID)
|
delete(rowIDToKey, rowID)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if currentKey != "" && currentKey != newKey {
|
if currentKey != "" && currentKey != newKey {
|
||||||
retired[currentKey] = struct{}{}
|
retired[currentKey] = rowID
|
||||||
delete(rowKeyToID, currentKey)
|
delete(rowKeyToID, currentKey)
|
||||||
}
|
}
|
||||||
if previousID, exists := rowKeyToID[newKey]; exists && previousID != rowID {
|
if previousID, exists := rowKeyToID[newKey]; exists && previousID != rowID {
|
||||||
@@ -4320,7 +4322,10 @@ func retireRowIdentity(row map[string]any, lockData map[string]int, retiredKeys
|
|||||||
if !ok || oldKey == "" {
|
if !ok || oldKey == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delete(lockData, oldKey)
|
rowID, _ := row["id"].(int)
|
||||||
|
if lockedID, ok := lockData[oldKey]; ok && lockedID == rowID {
|
||||||
|
delete(lockData, oldKey)
|
||||||
|
}
|
||||||
if retiredKeys != nil {
|
if retiredKeys != nil {
|
||||||
retiredKeys[oldKey] = struct{}{}
|
retiredKeys[oldKey] = struct{}{}
|
||||||
}
|
}
|
||||||
@@ -4348,7 +4353,9 @@ func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[s
|
|||||||
delete(row, "key")
|
delete(row, "key")
|
||||||
if oldKey != "" {
|
if oldKey != "" {
|
||||||
retiredKey = oldKey
|
retiredKey = oldKey
|
||||||
delete(lockData, oldKey)
|
if lockedID, ok := lockData[oldKey]; ok && lockedID == rowID {
|
||||||
|
delete(lockData, oldKey)
|
||||||
|
}
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
return changed, retiredKey, nil
|
return changed, retiredKey, nil
|
||||||
@@ -4358,7 +4365,9 @@ func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[s
|
|||||||
delete(row, "key")
|
delete(row, "key")
|
||||||
if oldKey != "" {
|
if oldKey != "" {
|
||||||
retiredKey = oldKey
|
retiredKey = oldKey
|
||||||
delete(lockData, oldKey)
|
if lockedID, ok := lockData[oldKey]; ok && lockedID == rowID {
|
||||||
|
delete(lockData, oldKey)
|
||||||
|
}
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
return changed, retiredKey, nil
|
return changed, retiredKey, nil
|
||||||
@@ -4386,7 +4395,9 @@ func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[s
|
|||||||
rowByKey[newKey] = row
|
rowByKey[newKey] = row
|
||||||
if oldKey != "" && oldKey != newKey {
|
if oldKey != "" && oldKey != newKey {
|
||||||
retiredKey = oldKey
|
retiredKey = oldKey
|
||||||
delete(lockData, oldKey)
|
if lockedID, ok := lockData[oldKey]; ok && lockedID == rowID {
|
||||||
|
delete(lockData, oldKey)
|
||||||
|
}
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
if existingID, ok := lockData[newKey]; ok {
|
if existingID, ok := lockData[newKey]; ok {
|
||||||
|
|||||||
@@ -6526,6 +6526,53 @@ func TestUpdateOverrideRowKeyRetiresOldKeyEvenIfReferenced(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateOverrideRowKeyDoesNotDeleteRelocatedReplacementLock(t *testing.T) {
|
||||||
|
row := map[string]any{"id": 58, "key": "baseitems:shortspear"}
|
||||||
|
rowByKey := map[string]map[string]any{
|
||||||
|
"baseitems:shortspear": row,
|
||||||
|
}
|
||||||
|
lockData := map[string]int{
|
||||||
|
"baseitems:shortspear": 126,
|
||||||
|
}
|
||||||
|
expanded := map[string]any{
|
||||||
|
"key": "baseitems:spear",
|
||||||
|
}
|
||||||
|
|
||||||
|
changed, retiredKey, err := updateOverrideRowKey("baseitems", row, expanded, rowByKey, lockData)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("updateOverrideRowKey failed: %v", err)
|
||||||
|
}
|
||||||
|
if !changed {
|
||||||
|
t.Fatal("expected key reassignment to mark the row changed")
|
||||||
|
}
|
||||||
|
if retiredKey != "baseitems:shortspear" {
|
||||||
|
t.Fatalf("expected retired key baseitems:shortspear, got %q", retiredKey)
|
||||||
|
}
|
||||||
|
if lockData["baseitems:shortspear"] != 126 {
|
||||||
|
t.Fatalf("expected relocated replacement lock to survive old row retirement, got %#v", lockData)
|
||||||
|
}
|
||||||
|
if lockData["baseitems:spear"] != 58 {
|
||||||
|
t.Fatalf("expected new row key to lock to row 58, got %#v", lockData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRetireRowIdentityDoesNotDeleteRelocatedReplacementLock(t *testing.T) {
|
||||||
|
row := map[string]any{"id": 916, "key": "feat:skill_focus_intimidate"}
|
||||||
|
lockData := map[string]int{
|
||||||
|
"feat:skill_focus_intimidate": 1333,
|
||||||
|
}
|
||||||
|
retiredKeys := map[string]struct{}{}
|
||||||
|
|
||||||
|
retireRowIdentity(row, lockData, retiredKeys)
|
||||||
|
|
||||||
|
if lockData["feat:skill_focus_intimidate"] != 1333 {
|
||||||
|
t.Fatalf("expected replacement lock to survive nulled old row, got %#v", lockData)
|
||||||
|
}
|
||||||
|
if _, ok := retiredKeys["feat:skill_focus_intimidate"]; !ok {
|
||||||
|
t.Fatalf("expected old row key to be recorded as retired")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildPrunesLockedIDThatTargetsManualBaseSpace(t *testing.T) {
|
func TestBuildPrunesLockedIDThatTargetsManualBaseSpace(t *testing.T) {
|
||||||
root := testProjectRoot(t)
|
root := testProjectRoot(t)
|
||||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
mkdirAll(t, filepath.Join(root, "topdata", "data", "dense", "modules"))
|
||||||
|
|||||||
Reference in New Issue
Block a user